From: shevegen@... Date: 2017-08-23T16:29:04+00:00 Subject: [ruby-core:82455] [Ruby trunk Bug#13837] Class attributes get overshadowed by local variables Issue #13837 has been updated by shevegen (Robert A. Heiler). I think hanmac already gave the correct answer so there is no point in me adding much to it. :) Note that you could specifically point ruby to call the getter method in the line hanmac pointed out, rather than using: bar = 0 if bar.nil? You could use: bar = 0 if self.bar.nil? And then the result would change. I took the liberty to reformat your input, so that other people have an easier time to copy/paste; the "irb" comments interfere there. I also commented it a tiny bit to make it more clear. Even the old pickaxe mentions that ruby may behave slightly unexpected in regards to assignments and local variables when it comes to nil class Foo attr_accessor :bar def initialize self.bar = 1 # Assigned 1 to @bar. end def hoge bar # Call reader method bar(). end def fuga bar = 0 if bar.nil? [bar, self.bar] end def baz if bar.nil? bar = 0 end end end foo = Foo.new p foo.bar p foo.hoge p foo.fuga p foo.bar p foo.baz # Returns: 1 1 [0, 1] 1 nil ---------------------------------------- Bug #13837: Class attributes get overshadowed by local variables https://bugs.ruby-lang.org/issues/13837#change-66266 * Author: valerauko (Balint Erdos) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: 2.4.1 * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- ~~~ ruby irb(main):001:0> RUBY_VERSION => "2.4.1" irb(main):002:0> class Foo irb(main):003:1> attr_accessor :bar irb(main):004:1> def initialize irb(main):005:2> self.bar = 1 irb(main):006:2> end irb(main):007:1> def baz irb(main):008:2> if bar.nil? irb(main):009:3> bar = 0 irb(main):010:3> end irb(main):011:2> end irb(main):012:1> def fuga irb(main):013:2> bar = 0 if bar.nil? irb(main):014:2> [bar, self.bar] irb(main):015:2> end irb(main):016:1> def hoge irb(main):017:2> bar irb(main):018:2> end irb(main):019:1> end => :hoge irb(main):020:0> foo = Foo.new => # irb(main):021:0> foo.bar => 1 irb(main):022:0> foo.hoge => 1 irb(main):023:0> foo.fuga => [0, 1] irb(main):024:0> foo.bar => 1 irb(main):025:0> foo.baz => nil ~~~ Even though the bar.nil? in fuga should not be true, it gets overwritten by the local variable preceding the if and thus evaluates true. I'd expect a behavior like below. It's really weird to get my class attributes overridden by a local variable that shouldn't even be evaluated. ~~~ ruby 1 if 2.nil? => nil ~~~ -- https://bugs.ruby-lang.org/ Unsubscribe: