Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The issue arrises with the way that Ruby deals with instance and local variables. What is happening is that you are setting a local variable in your instance_eval block, rather than using the ruby accessor.</p> <p>This might help explain it:</p> <pre><code>class Foo attr_accessor :bar def input_local bar = "local" [bar, self.bar, @bar, bar()] end def input_instance self.bar = "instance" [bar, self.bar, @bar, bar()] end def input_both bar = "local" self.bar = "instance" [bar, self.bar, @bar, bar()] end end foo = Foo.new foo.input_local #["local", nil, nil, nil] foo.input_instance #["instance", "instance", "instance", "instance"] foo.input_both #["local", "instance", "instance", "instance"] </code></pre> <p>The way bocks work is that they distinguish between local and instance variables, but if a local variable is not defined when it's reader is called, the class defaults to the instance variable (as is the case with the call to input_instance in my example).</p> <p>There are three ways to get the behavior you want.</p> <p>Use instance variables:</p> <pre> class Foo attr_accessor :bar def evaluate(&block) instance_eval &block end end foo = Foo.new foo.evaluate do @bar = "instance" end foo.bar #"instance" </pre> <p>Use a self variable:</p> <pre> class Foo attr_accessor :bar def evaluate(&block) block.call(self) end end foo = Foo.new foo.evaluate do |c| c.bar = "instance" end foo.bar #"instance" </pre> <p>Use setter functions:</p> <pre> class Foo attr_reader :bar def set_bar value @bar = value end def evaluate(&block) instance_eval &block end end foo = Foo.new foo.evaluate do set_bar "instance" end foo.bar #"instance" </pre> <p>All of these examples set foo.bar to "instance".</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