Jon wrote:
> Hi all,
> 
> I'm a 'ruby nubie' and otherwise unfamiliar with the ':eval' technique
> it employs.
> 
> Are there any decent reference guides to it's use?
> 
> Alternatively, can anyone give me a quick explanation of what, when and
> how to use it?
> 
> This for example, from an ajax scaffold im working on, makes little
> sense to me (it doesn't help that it's also Saturday afternoonr!)
> 
> :eval => "detail.bookings.collect{ |booking| booking.date }.join(', ')"
> 
> Many thanks,
> 
> Jon.
> 

You use eval with ajaxscaffold when you want to supply more complicated 
formula to display a cell value.
In simpler case you just use field name e.g.

AjaxScaffold::ScaffoldColumn.new(self, { :name => "some_field",:label => 
"some_label".r})

Then ajaxscaffold can use just send method to obtain field value.

When you use associations then case is more complicated:

AjaxScaffold::ScaffoldColumn.new(self, { :name => "some_field_id",:label 
=> "some_label".r, :eval => "some_model.some_field.some_property" , 
:filter => 'some_filter'})

and ajax scaffold must use eval to obtain a value (it is slower, but in 
ruby 1.8.5 seems to be quite fast)

the "detail.bookings.collect{ |booking| booking.date }.join(', ')" is 
quite complex so eval must be used

look for <% column_value = eval(scaffold_column.eval) rescue %>
in your generated ajaxscaffold code.

In simpler cases like "some_model.some_field.some_property" you could do 
  a send trick:

def send_eval s
     s.split('.').inject(self){|a,b| a.send(b.to_sym)}
end

but it seems that ruby's eval is a lot faster:


class A
     attr_accessor :a

     def x
         "foo"
     end
end

class B
     attr_accessor :a

     def initialize
         @a=A.new
     end
end

class C
     attr_accessor :b

     def initialize
         @b=B.new
     end
end


$c=C.new

def c
     $c
end

def send_eval s
     s.split('.').inject(self){|a,b| a.send(b.to_sym)}
end

s="c.b.a.x"

n = 10000
require 'benchmark'
Benchmark.bm do |x|
     x.report("eval") { n.times{ eval s } }
     x.report("send_eval") { n.times{ send_eval s } }
end

here are the results:

ruby 1.8.4:

       user     system      total        real
eval  0.219000   0.000000   0.219000 (  0.219000)
send_eval  0.343000   0.000000   0.343000 (  0.359000)


ruby 1.8.5 preview4

       user     system      total        real
eval  0.109000   0.000000   0.109000 (  0.117000)
send_eval  0.375000   0.000000   0.375000 (  0.374000)


lopex