33

I'm having trouble finding an authoritative example or discussion of this concept. If I have 2 variables in my Ruby method that are numbers, and I need to initialize them to zero. They will be used as counters. Is this OK or safe? It works in my tests.

Instead of this:

foo = 0
bar = 0

You can do this?

foo = bar = 0

It seems like a nice way to save on lines and still be expressive. Or, is this a bad practice? I realize I would be sacrificing readability a little. But, in a small Ruby method (<10 lines), that might not be a valid concern.

6 Answers 6

44

This works, but you should know that it's only safe for your situation because you're using the variables for numbers, which are immutable in Ruby. If you tried the same thing with a string, for example, you could end up with some behavior you didn't expect:

ruby-1.9.2-p180 :001 > foo = bar = "string"
 => "string" 
ruby-1.9.2-p180 :002 > foo.upcase!
 => "STRING" 
ruby-1.9.2-p180 :003 > bar
 => "STRING"
Sign up to request clarification or add additional context in comments.

Comments

33

It is fine practice to initialize two variables on the same line as long as the value being assigned as short and easy to follow. You can even assign two different values using the array syntax.

foo = bar = 123
foo #=> 123
bar #=> 123

foo, bar = 1, 2
foo #=> 1
bar #=> 2

1 Comment

Thanks! I rather like : foo, bar = 1, 2 I hadn't thought of that one. And it is still readable.
32

In many languages, the latter assigns the same object to both variables, which can be trouble if the object is mutable. Better to do this:

foo, bar = 0, 0

2 Comments

True in some languages, but irrelevant in Ruby for the question asked. IMO it's completely fine.
It works fine, but isn't recommended, less readable. github.com/bbatsov/ruby-style-guide#parallel-assignment
9

This is weird.

Ignacio Vazquez-Abrams answer is true for initializing variable with different values with:
a, b = 123, 456

But, I think your concern is on doing the following:
a = b = "hello"

But WAIT! The above line allocates same memory address for variables a and b i.e.
a.object_id and b.object_id are equal. So any changes on a would persist on b.

I don't like it, but a workaround could be.
x = "a very long string or something you don't want to type multiple times"
a, b, c = x.clone, x.clone, x.clone

Oh I wish there was an elegant way of doing this.

Comments

1

It's safe and it works.

Depends completely on your coding standard whether something like this is frowned upon or not.

Use it and leave for later refactoring when the time comes.

Comments

0

A possible solution, to assign the same value to different variables, is to call Array.new explicitly, like so:

a, b, c = Array.new(3, 0)

This wouldn't make a lot of sense for three variables, but could be more useful when assigning many more at once.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.