CrudVision - Lisa Seelye

June 28, 2007

Dynamic Proc Objects

Filed under: rails, ruby — Lisa Seelye @ 18:04

There's a problem. Proc objects can't be Marshalled which means they can't easily be stored.

I wrote a small method to build such a Dynamic proc first:

RUBY:
  1. def procbuilder(cmd,*r)
  2. argary = []
  3. r.each_index do |i|
  4. argary.push "arg_#{i}"
  5. end
  6. argstr = "|#{argary.join(',')}|"
  7. p = %q(Proc.new {) +  argstr  + ' ' + cmd + '}'
  8. eval p
  9. end

To use it:

RUBY:
  1. class Foo
  2. attr_accessor :foo
  3. def initalize
  4. end
  5. end
  6.  
  7. m = Foo.new
  8. m.foo = 10
  9.  
  10. # First parameter is the command to perform. arg_? is predictable
  11. # Following parameters are enumerated as arg_0, arg_1, arg_2
  12. p = procbuilder('arg_0.foo = arg_0.foo * arg_1',m,1.05)

And for output:

RUBY:
  1. puts p.call(m,1.05)
  2. puts m.foo

Result of the call is 10.5 and the instance on the object is changed too.

This is kind of cool but not much use unless there's a way to store it. Here's some Rails schema.rb:

RUBY:
  1. create_table "dyna_procs", :force => true do |t|
  2. t.column "name",       :string,   :null => false
  3. t.column "procsrc",    :text
  4. end

In the DynaProc model:

RUBY:
  1. attr_reader :dproc
  2. def after_initialize
  3. procbuilder(self.procsrc) unless self.procsrc.nil?
  4. end
  5.  
  6. private
  7. def procbuilder(cmd)
  8. @dproc = eval cmd
  9. end

Then after the DynaProc is loaded the dproc is a Proc object. Whee.

How the DynaProc object is created (and stored) is irrelevant. It could be from an custom form where people drag and drop predefined elements or it could be a scaffolded web form. White list everything and validate everything. Next trick is to get it to automatically sandbox itself...

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress