Question about abbreviated indexing assignments

  • Thread starter Jörg W Mittag
  • Start date
J

Jörg W Mittag

Hi!

According to the specification,

primary_expression[indexing_argument_list] ω= expression

is (roughly) evaluated like

o = primary_expression
*l = indexing_argument_list
v = o.[](*l)
w = expression
(v ω w).tap {|x|
l << x
o.[]=(*l)
}

In particular, this means that the assignment *always* takes place.
However, at least in some Ruby implementations (I tested MRI, YARV,
Rubinius, JRuby and IronRuby), this doesn't actually seem to be the
case, at least for some operators:

def (h = {int: 0}).[]=(k, v) p "Setting #{k} to #{v}"; super end
h[:int] += 1
# "Setting int to 1"
h[:int] += 1
# "Setting int to 2"

This calls the setter twice, as expected per the specification.

h[:key] ||= :value
# "Setting key to value"
h[:key] ||= :value

But this doesn't.

Since the purpose of the specification is to describe the currently
existing implementations, this is obviously a bug in the specification
rather than a bug in all five currently released implementations,
especially since there is a ton of code and even a common idiom that
depends on the current behavior. But what would the correct
specification look like?

Thanks in advance,
Jörg.
 
R

Rick DeNatale

It is commonly thought that x <operator>= y is exactly equivalent to x = x
<operator> y in all cases. What you have just demonstrated is that,
presumably for performance reasons, h[key] ||= value is in fact equivalent
to h[key] || h[key] = value, rather than h[key] = h[key] || value. This
prevents a second lookup in the case where k[key] exists and is not nil or
false.

x ||= y is NOT equivalent to x = x || y

Instead a closer approximation is

x || x = y

http://talklikeaduck.denhaven2.com/2008/04/26/x-y-redux


--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top