Forum: Ruby Code syntax comma usage

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jcm M. (Guest)
on 2009-02-14 20:05
That I can see; Pragmatic Programming Ruby's, index, has reference to
all sorts of symbols, but I can't find a explanation for a ',' seperator
such as used in the following:

 var1 = 1; p var1 #=> 1
 var2 = 2; p var2 #=> 2
 var3 = 3; p var3 #=> 3

 var1, var2, var3 = 5

 p var1 #=> 5
 p var2 #=> nil
 p var3 #=> nil

What's happening here? I read it as:
set var1 to 5 and reset var2 and var3 to nil.
Is that all the comma does?
Jeff M. (Guest)
on 2009-02-14 20:14
Jcm Mz wrote:
> That I can see; Pragmatic Programming Ruby's, index, has reference to
> all sorts of symbols, but I can't find a explanation for a ',' seperator
> such as used in the following:
>
>  var1 = 1; p var1 #=> 1
>  var2 = 2; p var2 #=> 2
>  var3 = 3; p var3 #=> 3
>
>  var1, var2, var3 = 5
>
>  p var1 #=> 5
>  p var2 #=> nil
>  p var3 #=> nil
>
> What's happening here? I read it as:
> set var1 to 5 and reset var2 and var3 to nil.
> Is that all the comma does?

Consider:

irb(main):005:0> a,b,c = 5,6,7
=> [5, 6, 7]

irb(main):006:0> a
=> 5

irb(main):007:0> b
=> 6

irb(main):008:0> c
=> 7

Multiple assignment from array parameters is very useful as well...

ra_parm = [1,2,3]

def meth(ra_parm)
 p1, p2, p3 = ra
end

Regards
Tom L. (Guest)
on 2009-02-14 20:17
(Received via mailing list)
> set var1 to 5 and reset var2 and var3 to nil.
> Is that all the comma does?

It can be used for parallel assignments:

a,b,c = [1,2,3]
a #=> 1
b #=> 2
c #=> 3

When you enter "var1, var2, var3 = 5" in irb, you'll get [5] as return
value. It seems the 5 gets silently converted into an array here.
Interesting.
Jeff M. (Guest)
on 2009-02-14 20:18
>
> Multiple assignment from array parameters is very useful as well...
>
> ra_parm = [1,2,3]
>
> def meth(ra_parm)
>  p1, p2, p3 = ra
> end
>
> Regards

Make that...

 def meth(ra_parm)
   p1, p2, p3 = ra_parm
 end
7stud -. (Guest)
on 2009-02-14 20:25
Jcm Mz wrote:
> That I can see; Pragmatic Programming Ruby's, index, has reference to
> all sorts of symbols, but I can't find a explanation for a ',' seperator
> such as used in the following:
>
>  var1 = 1; p var1 #=> 1
>  var2 = 2; p var2 #=> 2
>  var3 = 3; p var3 #=> 3
>
>  var1, var2, var3 = 5
>
>  p var1 #=> 5
>  p var2 #=> nil
>  p var3 #=> nil
>
> What's happening here?

It's called "parallel assignment".   Here is the basic case:

x, y = 10, 20
puts x   #10
puts y   #20


Then there are rules for dealing with the cases when the number of
variables on the left side do not equal the number of values on the
right side.  You are seeing the rule:  if there are more "lvalues" than
"rvalues", the excess lvalues will have nil assigned to them.

One of the little tricks you can do with parallel assignment is switch
values in two variables without using a third variable:

str = "hello"
num = 100
str, num = num, str

puts str   #100
puts num   #hello

Normally, if there are more rvalues than lvalues then the excess rvalues
are discarded, for example:

x, y = 10, 20, 100, 200
puts x   #10
puts y   #20


But you can also do this:

x, y, *remaining = 10, 20, 100, 200

puts x         #10
puts y         #20
p remaining    #[100, 200]

And this is also another way to do parallel assignment:

x, y, z = [10, 20, 30]
puts x   #10
puts y   #20
puts z   #30

In pickaxe2, a detailed description of parallel assignment is on p. 340.
matt neuburg (Guest)
on 2009-02-14 20:25
(Received via mailing list)
Jcm Mz <removed_email_address@domain.invalid> wrote:

> That I can see; Pragmatic Programming Ruby's, index, has reference to
> all sorts of symbols, but I can't find a explanation for a ',' seperator
> such as used in the following:
>
>  var1, var2, var3 = 5

You've stumbled on one of Ruby's most elegant bits of syntactical
niceness: multiple assignment. It isn't the comma that's interesting
here so much as the equal-sign and how it distributes assignments based
on lists. Try these:

arr = [1, 2, 3]

# now look at what a, b, and c are after each of the following:

a, b, c = 1, 2, 3
a, b, c = [1, 2, 3]
a = b, c
a, b = b, a
a, b, c = arr
a, b, c = arr, 4
a, b, c = 4, arr
a, b, c = 4, *arr

m.
Tom L. (Guest)
on 2009-02-14 21:19
(Received via mailing list)
> It seems the 5 gets silently converted into an array here.

The 5 doesn't get converted of course and [5] is the value of the
assignment. At times, I find ruby's permissiveness slightly
surprising.
David A. Black (Guest)
on 2009-02-14 21:27
(Received via mailing list)
Hi --

On Sun, 15 Feb 2009, Tom L. wrote:

>> It seems the 5 gets silently converted into an array here.
>
> The 5 doesn't get converted of course and [5] is the value of the
> assignment. At times, I find ruby's permissiveness slightly
> surprising.

That's been fixed in 1.9, so that a,b,c = 5 returns 5.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
7stud -. (Guest)
on 2009-02-14 22:31
Tom L. wrote:
>>When you enter "var1, var2, var3 = 5" in irb, you'll get [5] as return
>>value. It seems the 5 gets silently converted into an array here.
>>Interesting.
>
>
> The 5 doesn't get converted of course and [5] is the value of the
> assignment. At times, I find ruby's permissiveness slightly
> surprising.

The value of the assignment is written as 5, so if you end up with [5]
then it seems logical that something got converted.
David M. (Guest)
on 2009-02-14 23:02
(Received via mailing list)
Jeff M. wrote:
>
> Make that...
>
>  def meth(ra_parm)
>    p1, p2, p3 = ra_parm
>  end
>

Don't you need a splat for that?

def meth(ra_parm)
  p1, p2, p3 = *ra_parm
end
David A. Black (Guest)
on 2009-02-14 23:45
(Received via mailing list)
Hi --

On Sun, 15 Feb 2009, David M. wrote:

>>>
> def meth(ra_parm)
> p1, p2, p3 = *ra_parm
> end

No. If ra_parm is an array, it will assign in parallel to the
variables on the left.

irb(main):010:0> a,b,c = [1,2,3]
=> [1, 2, 3]
irb(main):011:0> a
=> 1
irb(main):012:0> b
=> 2
irb(main):013:0> c
=> 3


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
7stud -. (Guest)
on 2009-02-15 07:35
David M. wrote:
> Jeff M. wrote:
>>
>> Make that...
>>
>>  def meth(ra_parm)
>>    p1, p2, p3 = ra_parm
>>  end
>>
>
> Don't you need a splat for that?
>
> def meth(ra_parm)
>   p1, p2, p3 = *ra_parm
> end

1) You could test that yourself in less than 30 seconds.

2) You could actually read the thread and discover the answer:  there
are two posts containing the answer.
Jcm M. (Guest)
on 2009-02-15 09:00
Jcm Mz wrote:

> What's happening here? I read it as:
> set var1 to 5 and reset var2 and var3 to nil.
> Is that all the comma does?


The answer I was looking for was in fact the multiple assignment comma
operation.

The original code I was looking at was:

class Timer
  private
  def dispatch
     now  = Time.now.to_f
     ready, @queue = @queue.partition{|time, proc| time <= now }
     ready.each {|time, proc| proc.call((time)}
  end
end

p24 Practical Ruby Projects
This topic is locked and can not be replied to.