DRYing code through meta programming

I am using the following idiom to validate form data that is not
stored in a table:

class FormData < ActiveRecord::BaseWithoutTable
  column :date_column, :date
  column :int_column, :integer
  validates_date :date_column
  validates_numericality_of :int_column
end

unless request.get?
  @report = FormData.new(params[:report])
  @report.save
else
  @report = FormData.new
end

This works great (BaseWithoutTable and ValidatesDate are non-standard
packages), but it contains lots of boilerplate code that I’d like to
factor out. I would like to do something like this instead:

form_validate do
  column :date_column, :date
  column :int_column, :integer
  validates_date :date_column
  validates_numericality_of :int_column
end

but I’m unsure how I could do this. Something like:

def form_validate(init = {}, &block)
instance_eval <<-CODE
class Eval < ActiveRecord::BaseWithoutTable
#{block}
end
unless request.get?
@report = Eval.new(params[:report])
@report.save
else
@report = Eval.new(#{init})
end
CODE
end

doesn’t work. Do I need to use method_missing to parse the lines from
the block or is there a better way?

Hi –

On Mon, 29 Jan 2007, svenax wrote:

form_validate do
column :date_column, :date
column :int_column, :integer
validates_date :date_column
validates_numericality_of :int_column
end

I probably just haven’t had enough coffee, but I’m not seeing how this
differs significantly from what you’ve got above, in terms of amount
of code. Or is the savings inside the two add-on packages?

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Try some more coffee :wink:

Well, it would eliminate

unless request.get?
  @report = FormData.new(params[:report])
  @report.save
else
  @report = FormData.new
end

from each time I use this idiom.

Maybe I really want to ask the general question: How do I treat a code
block like a string to be used in some XXX_eval function? I can’t do
block.to_s can I? No, that would be too simple …

svenax wrote:

Maybe I really want to ask the general question: How do I treat a code
block like a string to be used in some XXX_eval function? I can’t do
block.to_s can I?

I thought most evals could take blocks as arguments, or as do-end
blocks. Do you mean you need to do string surgery to the block first?
I would try the opposite of “meta” programming, first. :slight_smile:


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!

On Jan 29, 6:20 pm, Phlip [email protected] wrote:

svenax wrote:

Maybe I really want to ask the general question: How do I treat a code
block like a string to be used in some XXX_eval function? I can’t do
block.to_s can I?I thought most evals could take blocks as arguments, or as do-end
blocks. Do you mean you need to do string surgery to the block first?
I would try the opposite of “meta” programming, first. :slight_smile:

That is exactly what I mean. Opposite? You mean hyperprogramming?

/sven axelsson

svenax wrote:

That is exactly what I mean. Opposite? You mean hyperprogramming?

No, uh, like… programmging. if statements. +. You know…


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!

svenax wrote:

So the question still stands: Is it possible to
stringify a code block in order to perform
some string surgery on it before handing it off to
an eval function?

Absolutely. What have you tried? What problem(s) did you have?

On Jan 30, 12:00 am, Phlip [email protected] wrote:

svenax wrote:

That is exactly what I mean. Opposite? You mean hyperprogramming?
No, uh, like… programmging. if statements. +. You know…

Yeah, so? I’ve alrady done that, so I thought it was time to try
something new.

So the question still stands: Is it possible to stringify a code block
in order to perform some string surgery on it before handing it off to
an eval function?