Note that there are some explanatory texts on larger screens.

plurals
  1. PODynamically added accessor assignment doesn't work when invoking block via instance_eval in Ruby
    text
    copied!<p>I have a class to which I add attribute accessors dynamically at runtime. This class forms part a DSL, whereby blocks get passed to configuration methods and invoked using instance_eval. This makes it possible in the DSL to remove references to 'self' when referencing methods of the class.</p> <p>However, I've discovered that I can reference the attributes to retrieve their values, but am unable to assign them, unless explicity referencing self, as the following code sample illustrates.</p> <pre><code>class Bar def add_dynamic_attribute_to_class(name) Bar.add_dynamic_attribute(name) end def invoke_block(&amp;block) instance_eval &amp;block end def self.add_dynamic_attribute(name) attr_accessor name end end b = Bar.new b.add_dynamic_attribute_to_class 'dyn_attr' b.dyn_attr = 'Hello World!' # dyn_attr behaves like a local variable in this case b.invoke_block do dyn_attr = 'Goodbye!' end # unchanged! puts "#{b.dyn_attr} but should be 'Goodbye!'" # works if explicitly reference self b.invoke_block do self.dyn_attr = 'Goodbye!' end # changed... puts "#{b.dyn_attr} = 'Goodbye!" # using send works b.invoke_block do send 'dyn_attr=', 'Hello Again' end # changed... puts "#{b.dyn_attr} = 'Hello Again!" # explain this... local variable or instance method? b.invoke_block do puts "Retrieving... '#{dyn_attr}'" # doesn't fail... but no effect dyn_attr = 'Cheers' end # unchanged puts "#{b.dyn_attr} should be 'Cheers'" </code></pre> <p>Can anyone explain why this isn't behaving as expected?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload