[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

iterating over array of variables - can't change t =?ISO-8859-1?Q?hem??=

AJS

1/4/2008 4:07:00 PM

title="Title"
subtitle="Subtitle"
body="Body"
[title,subtitle,body].each {|item| item.downcase!}

This successfully sets the original variables to "title", "subtitle",
"body"

BUT

[title,subtitle,body].each {|item| item=""}

has no effect.

Why doesn't this work? How can I make it work?

thanks
9 Answers

Drew Olson

1/4/2008 4:16:00 PM

0

AJS wrote:
> title="Title"
> subtitle="Subtitle"
> body="Body"
> [title,subtitle,body].each {|item| item.downcase!}
>

You're looking for map, which performs the action on each element and
creates a new array with the results:

[title,subtitle,body].map{|item| item.downcase}
--
Posted via http://www.ruby-....

Stefano Crocco

1/4/2008 4:16:00 PM

0

Alle venerd=EC 4 gennaio 2008, AJS ha scritto:
> title=3D"Title"
> subtitle=3D"Subtitle"
> body=3D"Body"
> [title,subtitle,body].each {|item| item.downcase!}
>
> This successfully sets the original variables to "title", "subtitle",
> "body"
>
> BUT
>
> [title,subtitle,body].each {|item| item=3D""}
>
> has no effect.
>
> Why doesn't this work? How can I make it work?
>
> thanks

The block variable (item) is set by ruby to "point to" each object of the=20
array in turn. String#downcase! is a destructive method: it changes its=20
receiver, so the elements of the original array get changed. On the other=20
hand, when you do item =3D "", you're telling the variable itewm to "point =
to"=20
another object, a new (empty) string. This doesn't modify the original arra=
y=20
at all.

If you want to change the contents of the original array, your should use=20
Array#map!:

[title,subtitle,body].map! {|item| ""}

Array#map! replaces each element of the array with the return value of the=
=20
block.

I hope this helps

Stefano

Robert Klemme

1/4/2008 4:21:00 PM

0

On 04.01.2008 17:06, AJS wrote:
> title="Title"
> subtitle="Subtitle"
> body="Body"
> [title,subtitle,body].each {|item| item.downcase!}
>
> This successfully sets the original variables to "title", "subtitle",
> "body"
>
> BUT
>
> [title,subtitle,body].each {|item| item=""}
>
> has no effect.
>
> Why doesn't this work? How can I make it work?

It does not work because you assign to "item" which is a local variable
in the block. And since you do not change string objects in the Array
you do not see any change. In your case you should change the original
object, e.g.

[title,subtitle,body].each {|item| item.replace ""}
[title,subtitle,body].each {|item| item.sub! /.*/, ""}

More generally you can also change the array via assignment by doing

an_array.map! { "" }

But this again won't change the objects referenced by "title" etc.

HTH

robert


Tomaso Tosolini

1/4/2008 4:22:00 PM

0

AJS wrote:

> title="Title"
> subtitle="Subtitle"
> body="Body"
> [title,subtitle,body].each {|item| item.downcase!}
>
> This successfully sets the original variables to "title", "subtitle",
> "body"
>
> BUT
>
> [title,subtitle,body].each {|item| item=""}

Hi
item="" sets item to reference to another string instead of the original at
the beginning of the block

try this

[title,subtitle,body].each {|item|

x = item
item=""
# this make item go to point away from it's original value

p x.inspect
# but x hasn't lost it's reference to initial value so it still
#works
}


Tom
>
> has no effect.
>
> Why doesn't this work? How can I make it work?
>
> thanks

Sebastian Hungerecker

1/4/2008 4:23:00 PM

0

AJS wrote:
> title="Title"
> subtitle="Subtitle"
> body="Body"
> [title,subtitle,body].each {|item| item.downcase!}
>
> This successfully sets the original variables to "title", "subtitle",
> "body"

No, it doesn't. It changes the strings, it doesn't do anything to the
variables. The variables still point to the same object as before, it's
just the objects that are different now.


> [title,subtitle,body].each {|item| item=""}
>
> has no effect.
>
> Why doesn't this work? How can I make it work?

It works just fine. It just doesn't do what you want it to. Here's what it
does:
It takes each of the elements in the array and then yields it. The code in the
block will then run with item pointing to the element. After the assignment
(item="") item will point to an empty string. This has no effect whatsoever
on the variables title, subtitle and body.
What you want is map instead of each (which gives you a new array containing
the results of yielding each item) or String#replace instead of reassignment
(which would change the object instead of the variable).


HTH,
Sebastian
--
Jabber: sepp2k@jabber.org
ICQ: 205544826

AJS

1/4/2008 4:33:00 PM

0

> [title,subtitle,body].map! {|item| ""}

perfect

thanks

Ken Bloom

1/4/2008 5:37:00 PM

0

On Fri, 04 Jan 2008 08:06:38 -0800, AJS wrote:

> title="Title"
> subtitle="Subtitle"
> body="Body"
> [title,subtitle,body].each {|item| item.downcase!}
>
> This successfully sets the original variables to "title", "subtitle",
> "body"
>
> BUT
>
> [title,subtitle,body].each {|item| item=""}
>
> has no effect.
>
> Why doesn't this work? How can I make it work?
>
> thanks

Refer to the variables as strings and use eval.

["title","subtitle","body"].each {|item| eval "#{item}=''"}

--Ken

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Robert Klemme

1/4/2008 8:01:00 PM

0

On 04.01.2008 18:36, Ken Bloom wrote:
> On Fri, 04 Jan 2008 08:06:38 -0800, AJS wrote:
>
>> title="Title"
>> subtitle="Subtitle"
>> body="Body"
>> [title,subtitle,body].each {|item| item.downcase!}
>>
>> This successfully sets the original variables to "title", "subtitle",
>> "body"
>>
>> BUT
>>
>> [title,subtitle,body].each {|item| item=""}
>>
>> has no effect.
>>
>> Why doesn't this work? How can I make it work?
>>
>> thanks
>
> Refer to the variables as strings and use eval.
>
> ["title","subtitle","body"].each {|item| eval "#{item}=''"}

I believe this is rather inefficient (aka slow) and more importantly
will not run under all circumstances ($SAFE). Plus, it's not needed. :-)

Kind regards

robert

Ken Bloom

1/6/2008 12:38:00 AM

0

On Fri, 04 Jan 2008 21:00:56 +0100, Robert Klemme wrote:

> On 04.01.2008 18:36, Ken Bloom wrote:
>> On Fri, 04 Jan 2008 08:06:38 -0800, AJS wrote:
>>
>>> title="Title"
>>> subtitle="Subtitle"
>>> body="Body"
>>> [title,subtitle,body].each {|item| item.downcase!}
>>>
>>> This successfully sets the original variables to "title", "subtitle",
>>> "body"
>>>
>>> BUT
>>>
>>> [title,subtitle,body].each {|item| item=""}
>>>
>>> has no effect.
>>>
>>> Why doesn't this work? How can I make it work?
>>>
>>> thanks
>>
>> Refer to the variables as strings and use eval.
>>
>> ["title","subtitle","body"].each {|item| eval "#{item}=''"}
>
> I believe this is rather inefficient (aka slow) and more importantly
> will not run under all circumstances ($SAFE). Plus, it's not needed.
> :-)

Whether or not it's needed depends entirely on how much he's condensed
the example to post it here. If he were interested in changing the class
of object, this is the only technique that would update the variables
automatically.

(So I'm doing more than the minimum needed to make the test case work, so
I'm not a real extreme programmer.)

--Ken

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...