First the benchmarks:
% ruby bm1.rb
user system total real
attr 15.250000 0.130000 15.380000 ( 18.405451)
attribute 64.520000 0.730000 65.250000 ( 74.519375)
irb(main):001:0> 74.519/18.405
=> a 4X slowdown
% ruby bm2.rb
user system total real
attr_accessor 0.130000 0.000000 0.130000 ( 0.185192)
attribute-plain 0.370000 0.010000 0.380000 ( 0.662546)
attribute-default 0.590000 0.010000 0.600000 ( 0.794125)
Then the comments:
Nice quiz. I have been using ruby for 6 years and have never needed
define_method.
The binding of the instance method fortytwo from the class scope was
something
I hadn't thought of. I now understand (I think) why one would use
define_method.
I also consider it a success when I can write code that doesn't
include all a bunch of
call to instance_variable_set/get. All in all, I think the code came
out pretty clean.
And lastly the code:
class Module
def attribute(*parms, &block)
return parms[0].each { |p,v| attribute(p) {v} } if parms
[0].kind_of?(Hash)
parms.each { |parm|
define_method("__#{parm}__", block) unless block.nil?
class_eval %{
attr_writer :#{parm}
def #{parm}
defined?(@#{parm}) ? @#{parm} : __#{parm}__
end
def #{parm}?
(defined?(@#{parm}) || defined?(__#{parm}__)) && !#
{parm}.nil?
end
}
}
end
end
== Or 10 lines of golf
class Module
def attribute(*parms, &block)
return parms[0].each { |p,v| attribute(p) {v} } if parms
[0].kind_of?(Hash)
parms.each { |parm|
define_method("__#{parm}__", block) unless block.nil?
class_eval %{attr_writer :#{parm}
def #{parm};defined?(@#{parm}) ? @#{parm} : __#{parm}__;end
def #{parm}?;(defined?(@#{parm}) || defined?(__#{parm}__))
&& !#{parm}.nil?;end}}
end
end
Jim Freeze