On 9/4/07, [email protected] [email protected] wrote:
I can’t point my finger on it but I believe x||=y is equivalent to
I’ve just looked at parse.y and eval.c for ruby1.8.6 and it would appear that:
goto again;
class C
Unless, of course, the object is a Hash which has either (a) a key
corresponding to the indicated value, or (b) a default value with
boolean truth value.
No, in the case you posited, the assignment happened and C#x= got
called because c.x returned nil.
irb(main):001:0> class D
irb(main):002:1> def x
irb(main):003:2> @x || 5
irb(main):004:2> end
irb(main):005:1> def x=(v)
irb(main):006:2> puts “x=called”
irb(main):007:2> @x = v
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> d = D.new
=> #<D:0xb7b47528>
irb(main):011:0> d.x ||= 10
=> 5
irb(main):012:0> d.x
=> 5
irb(main):013:0> d.x=10
x=called
=> 10
irb(main):014:0> d.x
=> 10
irb(main):015:0>
Sigh. I really wish it were otherwise. What an annoying exception to
the rule.
Except that the ‘rule’ wasn’t as you thought. The rule is that
x ||= y
is the same as
x = y unless x
Also, in the famous:
h = Hash.new(1)
h[5] ||= 10
case, it definitely isn’t doing the “x = x” equivalent, since that
would set the 5 key to 1.
And that’s as expected because h[5] returns the default value and
doesn’t affect the state of the hash a whit, it doesn’t create a 5
key. If you want the default to affect the hash you need something
like
hsh = Hash.new {|h,k| h[k] = 10}
$ fri Hash.new
-------------------------------------------------------------- Hash::new
Hash.new => hash
Hash.new(obj) => aHash
Hash.new {|hash, key| block } => aHash
Returns a new, empty hash. If this hash is subsequently accessed
by a key that doesn't correspond to a hash entry, the value
returned depends on the style of new used to create the hash. In
the first form, the access returns nil. If obj is specified, this
single object will be used for all default values. If a block is
specified, it will be called with the hash object and the key, and
should return the default value. It is the block's responsibility
to store the value in the hash if required.
h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"] #=> 100
h["c"] #=> "Go Fish"
# The following alters the single default object
h["c"].upcase! #=> "GO FISH"
h["d"] #=> "GO FISH"
h.keys #=> ["a", "b"]
Note the value of h.keys at the end of the RI example.
I don’t know… However many times I look at it, I just can’t see
this:
h[5] ||= 10
as not meaning that I expect h to end up having a 5 key, one way or
another.
Maybe just one more try?!
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/