Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
Thanks, P.
Hi --
Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
h = { :a => { :b => {} } }
tmp = h[:a][:b]
tmp[:x] = "hi"
tmp[:x] << " there"
p h # => {:a=>{:b=>{:x=>"hi there"}}}
You're (almost) always dealing in references in Ruby. (And the almost
part doesn't affect you much anyway.) Every reference is exactly one
step away from the object; there's no such thing as a reference to a
reference. It's very different from Perl in that respect.
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
I assume it's because (x ||= 1) evaluates to the object 1, and 1 *= 2
doesn't make sense.
David
···
On Thu, 23 Jul 2009, Pavel Smerk wrote:
--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)
Pavel Smerk schrieb:
Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
Thanks, P.
You can't get references of immediate values like Fixnums or Symbols. If you want a reference, the only way you could do is to get a reference to the innermost Hash:
irb(main):001:0> hsh = {1 => {2 => {3 => :value}}}
=> {1=>{2=>{3=>:value}}}
irb(main):002:0> hsh[1][2][3]
=> :value
irb(main):003:0> ref = hsh[1][2]
=> {3=>:value}
irb(main):004:0> ref[3] = :xyz
=> :xyz
irb(main):005:0> ref[3]
=> :xyz
irb(main):006:0> hsh[1][2][3]
=> :xyz
>Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
You try to assign a value to a Fixnum. The result of $x ||= 1 is 1 (if $x is unintitialized) and so your expression would evolve to:
1 = 1 * 2
which is invalid code.
Marvin
David A. Black wrote:
Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
h = { :a => { :b => {} } }
tmp = h[:a][:b]
tmp[:x] = "hi"
tmp[:x] << " there"
p h # => {:a=>{:b=>{:x=>"hi there"}}}
Yes, but I need something like:
$ ruby -e 'h = { :a => { :b => "hi" } }; tmp = h[:a][:b]; tmp << " there"; p h'
{:a=>{:b=>"hi there"}}
which is OK, but not for Float:
$ ruby -e 'h = { :a => { :b => 5.0 } }; tmp = h[:a][:b]; tmp += 5.0; p h'
{:a=>{:b=>5.0}}
And that's why I'm asking for a "real" reference, because tmp apparently is not any kind of reference to the h[:a][:b].
You're (almost) always dealing in references in Ruby. (And the almost
part doesn't affect you much anyway.) Every reference is exactly one
step away from the object; there's no such thing as a reference to a
reference. It's very different from Perl in that respect.
Mhm, an unfortunate difference, I'm afraid...
Of course, I could write tmp = h[:a] and then many times tmp[:b]. But something like simple tmp as in Perl would seem to me far more elegant.
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
I assume it's because (x ||= 1) evaluates to the object 1, and 1 *= 2
doesn't make sense.
I know, my question is, why it does not evaluate to x. Then it would have the same value (the value of x) and moreover it could stand on the left side of an another assignment (as the x *= 2 does make sense).
Thanks, P.
···
On Thu, 23 Jul 2009, Pavel Smerk wrote:
You're (almost) always dealing in references in Ruby. (And the almost
part doesn't affect you much anyway.) Every reference is exactly one
step away from the object; there's no such thing as a reference to a
reference. It's very different from Perl in that respect.
Mhm, an unfortunate difference, I'm afraid...
[...]
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
I assume it's because (x ||= 1) evaluates to the object 1, and 1 *= 2
doesn't make sense.
I know, my question is, why it does not evaluate to x. Then it would have the same value (the value of x) and moreover it could stand on the left side of an another assignment (as the x *= 2 does make sense).
It doesn't evaluate to x because Ruby isn't Perl. It isn't like there is an absolute right or wrong way to design a language. Each language has its own idioms and techniques, some of which are not translatable from one language to the next.
$ ruby -e 'h = { :a => { :b => "hi" } }; tmp = h[:a][:b]; tmp << " there"; p h'
{:a=>{:b=>"hi there"}}
which is OK, but not for Float:
$ ruby -e 'h = { :a => { :b => 5.0 } }; tmp = h[:a][:b]; tmp += 5.0; p h'
{:a=>{:b=>5.0}}
And that's why I'm asking for a "real" reference, because tmp apparently is not any kind of reference to the h[:a][:b].
Variables in Ruby hold references to objects. They are not labels for memory where values are stored. Your example should be written as:
h[:a][:b] += 5.0
Gary Wright
···
On Jul 23, 2009, at 10:25 AM, Pavel Smerk wrote:
David A. Black wrote:
Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
h = { :a => { :b => {} } }
tmp = h[:a][:b]
tmp[:x] = "hi"
tmp[:x] << " there"
p h # => {:a=>{:b=>{:x=>"hi there"}}}
Yes, but I need something like:
$ ruby -e 'h = { :a => { :b => "hi" } }; tmp = h[:a][:b]; tmp << " there"; p h'
{:a=>{:b=>"hi there"}}
which is OK, but not for Float:
$ ruby -e 'h = { :a => { :b => 5.0 } }; tmp = h[:a][:b]; tmp += 5.0; p h'
{:a=>{:b=>5.0}}
And that's why I'm asking for a "real" reference, because tmp apparently is not any kind of reference to the h[:a][:b].
Well, it is, but Fixnum's are immediate (implementation detail) and Float's act like value objects. What would happen if:
5.0 += 5.0
were legal? All 5's now act like 10's??
You're (almost) always dealing in references in Ruby. (And the almost
part doesn't affect you much anyway.) Every reference is exactly one
step away from the object; there's no such thing as a reference to a
reference. It's very different from Perl in that respect.
Mhm, an unfortunate difference, I'm afraid...
Of course, I could write tmp = h[:a] and then many times tmp[:b]. But something like simple tmp as in Perl would seem to me far more elegant.
Morover, why the return value of the assignment is not an l-value? The following is legal in Perl ($x ||= 1) *= 2 --- why it is not legal in Ruby as well?
I assume it's because (x ||= 1) evaluates to the object 1, and 1 *= 2
doesn't make sense.
I know, my question is, why it does not evaluate to x. Then it would have the same value (the value of x) and moreover it could stand on the left side of an another assignment (as the x *= 2 does make sense).
Thanks, P.
Because in Ruby, "x.y = z" is just syntactic sugar when x is an object for:
x.send(:y=, z)
with the rule that the "value" of an assignment is the right-hand side (i.e., z) so things like
w = x.y = z
are predictable (meaning that the "y=" method sent to x can't return something other than z for the assignment to w. (And, the rule breaks down if you don't use the sugar, but make the calls yourself:
w = x.send(:y=, z)
might result in w != z, but any programmer that does such a thing in "real" code should be punished.)
-Rob
Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
···
On Jul 23, 2009, at 10:25 AM, Pavel Smerk wrote:
On Thu, 23 Jul 2009, Pavel Smerk wrote:
Hi --
David A. Black wrote:
Assume a big hash and/or a nested structure and the need of a plenty of operations on some hash[...][...][...] which is Float. How can one avoid the repetitious evaluation of the indices? I have not been able to get a "real" reference to that variable to do _something_like_ tmp = referenceof(hash[...][...][...]) and work with the value directly through the (dereferenced) tmp variable. In Perl I would say
$ perl -e '$x[1][2][3] = 1; $a = \$x[1][2][3]; $$a = 3; print $x[1][2][3]'
3
(where \... is a reference and $ before $a is a dereference).
h = { :a => { :b => {} } }
tmp = h[:a][:b]
tmp[:x] = "hi"
tmp[:x] << " there"
p h # => {:a=>{:b=>{:x=>"hi there"}}}
Yes, but I need something like:
$ ruby -e 'h = { :a => { :b => "hi" } }; tmp = h[:a][:b]; tmp << " there"; p h'
{:a=>{:b=>"hi there"}}
which is OK, but not for Float:
$ ruby -e 'h = { :a => { :b => 5.0 } }; tmp = h[:a][:b]; tmp += 5.0; p h'
{:a=>{:b=>5.0}}
And that's why I'm asking for a "real" reference, because tmp apparently is not any kind of reference to the h[:a][:b].
Right; I wasn't taking into account the fact that your example was
dealing with numbers.
You're (almost) always dealing in references in Ruby. (And the almost
part doesn't affect you much anyway.) Every reference is exactly one
step away from the object; there's no such thing as a reference to a
reference. It's very different from Perl in that respect.
Mhm, an unfortunate difference, I'm afraid...
You'll have to talk to Larry about fixing it
Seriously though... I
would advise you strongly not to compare Ruby and Perl token-by-token
or construct-by-construct. It's like criticizing a flute because it
doesn't have strings.
Of course, I could write tmp = h[:a] and then many times tmp[:b]. But something like simple tmp as in Perl would seem to me far more elegant.
The two languages have completely different variable and assignment
semantics. Again, I'd try to get to know Ruby on its own terms.
There's plenty of elegance to be had there 
David
···
On Thu, 23 Jul 2009, Pavel Smerk wrote:
On Thu, 23 Jul 2009, Pavel Smerk wrote:
--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)