Fork me on GitHub

rubyless

An article by Gaspard Bucher

rubyless icon

RubyLess is an interpreter for “safe ruby”. The idea is to transform some “unsafe” ruby code into safe, type checked ruby, eventually rewriting some variable names.

There is not much current documentation, but the test in the source repository should give some hints.

source code: github.com/zena/rubyless

installation

# sudo gem install rubyless

example

You declare safe methods like this in your classes:

class Foo
  include RubyLess
  safe_method :hello => String
  
  def hello
    "Hello World!"
  end
end

class Bar
  include RubyLess
  safe_method :foo => {:class => Foo, :method => 'Foo.new'}
end

RubyLess.translate("foo.hello", Bar) # --> Foo.new.hello

The Bar in the “translate” method is used to indicate the binding context where RubyLess should start compilation. The code produced above is thus meant to be evaluated in the context of a Bar object.

what for ?

RubyLess is used as a way to safely evaluate “unsafe” code. For example, we use RubyLess in zafu to declare the model and helper methods that are available in the templates.

Using RubyLess avoids creating yet another DSL. We can just use ruby syntax and parsing.

advanced features

Safe definitions that you declare in a module are propagated to any class that mixes this module in. This enables the use of RubyLess in helpers (zafu templates use this a lot in Rails helpers).

Another nice feature of RubyLess is clever with the hash arguments idiom used a lot in Ruby. You can declare optional arguments with a Hash:

module PageHelper
  include RubyLess
  safe_method [:link, Page, {'title' => String, 'class' => String}] => String
  
  def link(page, opts={})
    # ...
  end
end

All arguments in the hash should be optional (actually, even the hash itself should not be mandatory). The above definition will happily accept code such as this (if ‘title’ is a safe method in Page):

link(@page, 'title' => @page.title)

I am not sure all this is very clear… Don’t hesitate to ask the community if you have any questions.