Right, the question is why in Ruby 1.9 is using the 'not a test'
returned from the setter method in the case of ||= unlike Ruby 1.8.x
and like itself in the = case:
To make it a bit clearer by moving the assignments out of the p calls:
puts RUBY_VERSION
class OrOrEquals
def test @test
end
def test=(test) @test = test
'not test'
end
end
o = OrOrEquals.new
direct = o.test = 'a test'
p direct
o.test = nil
with_oror = o.test ||= 'a test'
p with_oror
p o.test
o.test = nil
VERSION = 1.8.6-p368
CMD = ~/.multiruby/install/1.8.6-p368/bin/ruby or_or_equals.rb
1.8.6
"a test"
"a test"
"a test"
RESULT = 0
VERSION = 1.8.7-p160
CMD = ~/.multiruby/install/1.8.7-p160/bin/ruby or_or_equals.rb
1.8.7
"a test"
"a test"
"a test"
RESULT = 0
VERSION = 1.9.1-p0
CMD = ~/.multiruby/install/1.9.1-p0/bin/ruby or_or_equals.rb
1.9.1
"a test"
"not test"
"a test"
I've raised this on ruby-core. I'm interested to see what Matz & co
have to say.
···
On Wed, Aug 26, 2009 at 2:49 PM, Aldric Giacomoni<aldric@trevoke.net> wrote:
Joel VanderWerf wrote:
Well, then... It -IS- assigning something, isn't it, since there's no
value to @test ? Why does it return something other than the result of
the assignment?
Right, the question is why in Ruby 1.9 is using the 'not a test'
returned from the setter method in the case of ||= unlike Ruby 1.8.x
and like itself in the = case:
According the rubyspec project:
language/variables_spec.rb:
describe "Operator assignment 'var op= expr'" do
it "is equivalent to 'var = var op expr'" do
x = nil
(x ||= 17).should == 17
x.should == 17
(x ||= 2).should == 17
x.should == 17
describe "Operator assignment 'obj.meth op= expr'" do
it "is equivalent to 'obj.meth = obj.meth op expr'" do @x.a = nil
(@x.a ||= 17).should == 17 @x.a.should == 17
(@x.a ||= 2).should == 17 @x.a.should == 17
describe "Operator assignment 'obj[idx] op= expr'" do
it "is equivalent to 'obj[idx] = obj[idx] op expr'" do
x = [1,nil,12]
(x[1] ||= 17).should == 17
x.should == [1,17,12]
(x[1] ||= 2).should == 17
x.should == [1,17,12]
it "returns result of rhs not result of =" do
a = VariablesSpecs::Hashalike.new
(a[123] = 2).should == 2
(a[123] ||= 2).should == 123
(a[nil] ||= 2).should == 2
The specs don't address the case of a 'hijacked' setter, but they do
give the impression that the ruby1.9 behaviour is incorrect.
I've raised this on ruby-core. I'm interested to see what Matz & co
have to say.
Yes, should be interesting.
···
On Wed, Aug 26, 2009 at 3:46 PM, Rick DeNatale<rick.denatale@gmail.com> wrote:
On Wed, Aug 26, 2009 at 3:46 PM, Rick DeNatale<rick.denatale@gmail.com> wrote:
Right, the question is why in Ruby 1.9 is using the 'not a test'
returned from the setter method in the case of ||= unlike Ruby 1.8.x
and like itself in the = case:
According the rubyspec project:
language/variables_spec.rb:
describe "Operator assignment 'var op= expr'" do
it "is equivalent to 'var = var op expr'" do
It isn't, though, at least in the ||= case (see Joel W.'s post).
Matz's characterization of it to me at RubyConf (or somewhere) was:
x ||= y same as x || x = y
David
--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
Instructors: David A. Black and Erik Kastner
More info and registration: http://rubyurl.com/vmzN
o.x ||= y
o.x = o.x || y
# .x= is always called
o.x || o.x = y
# .x= is not always called
o.x += y
o.x = o.x + y
Then maybe ||= and += should be split apart in rubyspec:
describe "var += expr" it "is equivalent to 'var = var op expr'"
describe "var ||= expr" it "is equivalent to 'var || var = expr'"
···
On Wed, Aug 26, 2009 at 5:23 PM, David A. Black<dblack@rubypal.com> wrote:
Hi --
On Thu, 27 Aug 2009, brabuhr@gmail.com wrote:
According the rubyspec project:
language/variables_spec.rb:
describe "Operator assignment 'var op= expr'" do
it "is equivalent to 'var = var op expr'" do
It isn't, though, at least in the ||= case (see Joel W.'s post).
Matz's characterization of it to me at RubyConf (or somewhere) was:
On Wed, Aug 26, 2009 at 5:23 PM, David A. Black<dblack@rubypal.com> wrote:
It isn't, though, at least in the ||= case (see Joel W.'s post).
Matz's characterization of it to me at RubyConf (or somewhere) was:
x ||= y same as x || x = y
It's approximately the same as certainly closer than x = x || y
There's a difference in what happens if x is not previously defined
True. Maybe this?
defined?(x) && x || x = y
David
--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
Instructors: David A. Black and Erik Kastner
More info and registration: http://rubyurl.com/vmzN
>> According the rubyspec project:
>>
>> language/variables_spec.rb:
>> describe "Operator assignment 'var op= expr'" do
>> it "is equivalent to 'var = var op expr'" do
>
>It isn't, though, at least in the ||= case (see Joel W.'s post).
>Matz's characterization of it to me at RubyConf (or somewhere) was:
>
> x ||= y same as x || x = y
Basically, "var op= expr" works like "var = var op expr" but left hand
side expression (var) is evaluated only once. For ||=, it is same as
x = (x || y)
but
x || (x = y)
is semantically same (well, almost).
The hash case, though, definitely points to x || (x = y):
h = Hash.new(5)
=> {}
h[:x] = (h[:x] || 1)
=> 5
h
=> {:x=>5}
h[:z] || (h[:z] = 1)
=> 5
h
=> {:x=>5}
h[:y] ||= 1
=> 5
h
=> {:x=>5}
David
···
On Thu, 27 Aug 2009, Yukihiro Matsumoto wrote:
In message "Re: ||= with 1.8 and 1.9 ?" > on Thu, 27 Aug 2009 06:23:01 +0900, "David A. Black" <dblack@rubypal.com> writes:
--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
Instructors: David A. Black and Erik Kastner
More info and registration: http://rubyurl.com/vmzN
I've never understood ||=. As a result, I would never use it in my
code. As far as I'm concerned, I can explicitly write what I want
rather than trust some unpredictable, quirky short hand operator.