my code has # symbol in class_eval section. foreign me, mean?
class class def attr_accessor_with_history(attr_name) attr_name = attr_name.to_s # make sure it's string attr_reader attr_name # create attribute's getter attr_reader attr_name+"_history" # create bar_history getter class_eval %q{ def #{attr_name}=(attr_name) @#{attr_name} = attr_name @#{attr_name}_history = [nil] if @#{attr_name}_history.nil? @#{attr_name}_history << attr_name end } end end
def #{attr_name}=(attr_name) @#{attr_name} = attr_name @#{attr_name}_history = [nil] if @#{attr_name}_history.nil? @#{attr_name}_history << attr_name end if attr_name variable equal to, let's say, "params". transform this:
def params=(attr_name) @params = attr_name @params_history = [nil] if @params_history.nil? @params_history << attr_name end why happens? because of called string interpolation. if write #{something} inside string, something evaluated , replaced inside string.
and why whould above code work though it's not in string?
the answer is, because is!
ruby gives different ways things, , there alternative syntax literals, goes that: %w{one 2 three} {} delimiter, long use same or corresponding closing one. %w\one 2 three\ or %w[one 2 three], work.
that one, %w arrays, %q double-quoted string. if wanna see of them, suggest take @ this: http://www.ruby-doc.org/docs/programmingruby/html/language.html
now, in code
class class def attr_accessor_with_history(attr_name) attr_name = attr_name.to_s # make sure it's string attr_reader attr_name # create attribute's getter attr_reader attr_name+"_history" # create bar_history getter class_eval %q{ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # string begins def #{attr_name}=(attr_name) @#{attr_name} = attr_name @#{attr_name}_history = [nil] if @#{attr_name}_history.nil? @#{attr_name}_history << attr_name end } <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # string ends end end we can see whole part string interpolation inside %q{ }. means entire block big double-quoted string. , that's why string interpolation it's job before sending string eval.
Comments
Post a Comment