Beginner's question: assigning same value to many variables

A

Alex Khere

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).
 
E

Eero Saynatkari

Alex said:
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.
 
S

Suraj N. Kurapati

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
%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-----
 
A

Alex Khere

Eero said:
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.
 
D

dblack

Hi --

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

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
http://www.manning.com/black => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.
 
C

Chad Perrin

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.
 
D

dblack

M

Morton Goldberg

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
 
G

Gennady Bystritsky

-----Original Message-----
From: Morton Goldberg [mailto:[email protected]]=20
Sent: Friday, August 11, 2006 9:21 PM
To: ruby-talk ML
Subject: Re: Beginner's question: assigning same value to=20
many variables
=20
I presume you want each variable initialized to a _different_ empty =20
string. If so, I can't think of an easy way to do it using local =20
variables. That may just go to show my lack of ruby smarts. However, =20
it's not too hard to initialize a group of instance variables to =20
different empty strings in one line of code. Consider:
=20
#! /usr/bin/ruby -w
=20
class Foo
def initialize
%w[@a @b @c @d].each {|v| instance_variable_set(v, '')}
end
end
=20
foo =3D Foo.new
p foo #=3D> #<Foo:0x2556c @c=3D"", @b=3D"", @a=3D"", @d=3D"">
=20
And the following will work for global variables.
=20
%w[$a, $b, $c, $d].each {|v| eval("%s=3DString.new" % v)}
p [$a, $b, $c, $d] #=3D> ["", "", "", ""]
=20
But for local variables, I don't know.

How about this:

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

It will work for global and instance variables as well.

Best,=20
Gennady.
 
A

Alexandru E. Ungur

sender: "Morton Goldberg" 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
Or even a bit shorter:

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

Cheers,
Alex
 
M

Morton Goldberg

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
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top