Beginner's question: assigning same value to many variables

I’m just starting out in programming, using Ruby to learn.

I’m trying to write a short program that will use a handful of
variables, and I want to be sure that all of the variables start with
the value ‘’ (strings of zero length).

Is there a way to list all of the variables on a single line and set
them to the same value? I tried using commas to seperate, but that
didn’t work.

I also tried creating an array with all of the variable names and then
using “arrayname.each do |name|” to cycle through the assignment, but
since the varibles hadn’t been defined, I got an “undefined local
variable or method” error (at least, I think that’s why I got an error).

Alex Khere wrote:

I’m just starting out in programming, using Ruby to learn.

I’m trying to write a short program that will use a handful of
variables, and I want to be sure that all of the variables start with
the value ‘’ (strings of zero length).

Is there a way to list all of the variables on a single line and set
them to the same value? I tried using commas to seperate, but that
didn’t work.

I also tried creating an array with all of the variable names and then
using “arrayname.each do |name|” to cycle through the assignment, but
since the varibles hadn’t been defined, I got an “undefined local
variable or method” error (at least, I think that’s why I got an error).

In ruby there are no statements, just expressions. Therefore:

@a = @b = 0

The one caveat, though, is that the references are the same
which means that, for example, assigning “hello” this way
might lead to some confusing results.

Some alternatives include:

@a, @b = 0, 0

@a, @b = Array.new(2) {“Hello”}

Another popular idiom is to defer the initialisation to the
point of first use of the variable. For this the || operator
is often used:

do_something_with(@a || default_value)

do_something_else_with(@b ||= other_default)

The latter operator is shorthand for (@b = @b || default) which
will also assign the default to @b for future use.

Eero S. wrote:

In ruby there are no statements, just expressions. Therefore:

@a = @b = 0

The one caveat, though, is that the references are the same
which means that, for example, assigning “hello” this way
might lead to some confusing results…

Thank you, the first example will probably work in this case, but I can
experiment with your other examples.

a=b=c=d=f=g=h=i=j=k=l=m=n=’’

or you could do

%w{ a b c d e f g h i j }.each {|v| eval “#{v}=’’” }

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mark Van H. wrote:

%w{ a b c d e f g h i j }.each {|v| eval “#{v}=’’” }

Isn’t that considered evil? Using eval on a string, that is.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFE3RZ4mV9O7RYnKMcRAhmhAJ441UdVf3buQW8zgk5mJsvJjcjarQCfUG9i
o4EV0AnygtsrSBhrQsGUh1A=
=LLzM
-----END PGP SIGNATURE-----

On Sat, Aug 12, 2006 at 08:45:43AM +0900, Suraj N. Kurapati wrote:

Mark Van H. wrote:

%w{ a b c d e f g h i j }.each {|v| eval “#{v}=’’” }

Isn’t that considered evil? Using eval on a string, that is.

Maybe we should call it “evil” instead of “eval”, then.

Hi –

On Sat, 12 Aug 2006, Mark Van H. wrote:

didn’t work.

I also tried creating an array with all of the variable names and then
using “arrayname.each do |name|” to cycle through the assignment, but
since the varibles hadn’t been defined, I got an “undefined local
variable or method” error (at least, I think that’s why I got an error).

a=b=c=d=f=g=h=i=j=k=l=m=n=’’

But beware:

a=b=c=’’
a << “hi”
puts b # hi

David

On Sat, Aug 12, 2006 at 08:57:37AM +0900, [email protected] wrote:

On Sat, 12 Aug 2006, Mark Van H. wrote:

or you could do

%w{ a b c d e f g h i j }.each {|v| eval “#{v}=’’” }

That won’t work; they’ll go out of scope. Actually out of two scopes:
the eval scope, and the #each block scope.

. . . which is great if you’re trying to construct a closure, but not so
great otherwise.

Hi –

On Sat, 12 Aug 2006, Mark Van H. wrote:

or you could do

%w{ a b c d e f g h i j }.each {|v| eval “#{v}=’’” }

That won’t work; they’ll go out of scope. Actually out of two scopes:
the eval scope, and the #each block scope.

David

Hi –

On Sat, 12 Aug 2006, Chad P. wrote:

. . . which is great if you’re trying to construct a closure, but not so
great otherwise.

I don’t think it’s ever good for variables you want to use to be out
of scope :slight_smile:

David

I presume you want each variable initialized to a different empty
string. If so, I can’t think of an easy way to do it using local
variables. That may just go to show my lack of ruby smarts. However,
it’s not too hard to initialize a group of instance variables to
different empty strings in one line of code. Consider:

#! /usr/bin/ruby -w

class Foo
def initialize
%w[@a @b @c @d].each {|v| instance_variable_set(v, ‘’)}
end
end

foo = Foo.new
p foo #=> #<Foo:0x2556c @c="", @b="", @a="", @d="">

And the following will work for global variables.

%w[$a, $b, $c, $d].each {|v| eval("%s=String.new" % v)}
p [$a, $b, $c, $d] #=> ["", “”, “”, “”]

But for local variables, I don’t know.

Regards, Morton

it’s not too hard to initialize a group of instance variables to
foo = Foo.new
p foo #=> #<Foo:0x2556c @c="", @b="", @a="", @d="">

And the following will work for global variables.

%w[$a, $b, $c, $d].each {|v| eval("%s=String.new" % v)}
p [$a, $b, $c, $d] #=> ["", “”, “”, “”]

But for local variables, I don’t know.

How about this:

irb(main):001:0> a, b, c = Array.new(3) { ‘’ }
=> ["", “”, “”]
irb(main):002:0> a
=> “”
irb(main):003:0> b
=> “”
irb(main):004:0> c
=> “”
irb(main):005:0> a.object_id
=> 203740
irb(main):006:0> b.object_id
=> 203730
irb(main):007:0> c.object_id
=> 203720
irb(main):008:0>

It will work for global and instance variables as well.

Best,
Gennady.

I like it. I’s a much better idea than either of mine.

Regards, Morton

No, that doesn’t work. We want each variable initialized to a
different empty string.

a, b, c, d = Array.new(4) { ‘’ }
p [a, b, c, d].collect {|i| i.object_id} #=> [74020, 74010, 74000,
73990]

a, b, c, d = Array.new(4,’’)
p [a, b, c, d].collect {|i| i.object_id} #=> [73920, 73920, 73920,
73920]

a, b, c, d = [’’] * 4
p [a, b, c, d].collect {|i| i.object_id} #=> [73820, 73820, 73820,
73820]

Regards, Morton

sender: “Morton G.” date: “Sun, Aug 13, 2006 at 02:18:16AM +0900” <<<EOQ
I like it. I’s a much better idea than either of mine.

Regards, Morton

On Aug 12, 2006, at 2:39 AM, Gennady B. wrote:

irb(main):001:0> a, b, c = Array.new(3) { ‘’ }
Or even a bit shorter:

a, b, c = Array.new(3,’’) OR
a, b, c = [’’] * 3

Cheers,
Alex