[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

block and method local variables

Daniel Schüle

1/4/2006 12:46:00 AM

hello all,

consider follow code

irb(main):528:0* def abc
irb(main):529:1> ppp=111
irb(main):530:1> puts ppp
irb(main):531:1> yield
irb(main):532:1> puts ppp
irb(main):533:1> ppp
irb(main):534:1> end
=> nil
irb(main):536:0> abc {}
111
111
=> 111
irb(main):537:0> abc { puts ppp }
111
NameError: undefined local variable or method `ppp' for main:Object
from (irb):537
from (irb):537:in `abc'
from (irb):537
from :0
irb(main):538:0>
irb(main):539:0*
irb(main):540:0* ppp = "OOO"
=> "OOO"
irb(main):541:0> abc { puts ppp }
111
OOO
111
=> 111
irb(main):542:0>

I am right assuming that all "local" variables in the method abc
are invisible in the block?

I tried a little more

irb(main):544:0* def cba
irb(main):545:1> ppp = 222
irb(main):546:1> puts ppp
irb(main):547:1> yield ppp
irb(main):548:1> puts ppp
irb(main):549:1> ppp
irb(main):550:1> end
=> nil
irb(main):551:0> cba {}
222
222
=> 222
irb(main):552:0> cba {|p|}
222
222
=> 222
irb(main):553:0> cba {|p| p = 333}
222
222
=> 222
irb(main):554:0> cba {|p| puts p; p = 333}
222
222
222
=> 222
irb(main):555:0>

if explicitely passed to block ppp is now visible there.
but seems to be imposible to change the "method local" variable
ppp in this case.

the following *does* work

irb(main):557:0* def xxx
irb(main):558:1> ppp = [1]
irb(main):559:1> p ppp
irb(main):560:1> yield ppp
irb(main):561:1> p ppp
irb(main):562:1> ppp
irb(main):563:1> end
=> nil
irb(main):564:0> xxx {}
[1]
[1]
=> [1]
irb(main):565:0> xxx {|x| }
[1]
[1]
=> [1]
irb(main):566:0> xxx {|x| x[0]=2 }
[1]
[2]
=> [2]
irb(main):567:0>

and I kind of understand why it works

if I change line 566 to
irb(main):566:0> xxx {|x| x=[2] }
than it would not work

the reason I came accross this is following
I was reading

"
Parameters to a block may be existing local variables; if so, the new
value of the variable will be retained after the block completes. This
may lead to unexpected behavior, but there is also a performance gain to
be had by using variables that already exist
"
and in my understanding all variables defined in a method
are "local" (C++ background)

If not local what are they considered to be then?

Regards, Daniel

8 Answers

Ross Bamford

1/4/2006 12:58:00 AM

0

On Wed, 04 Jan 2006 00:46:16 -0000, Daniel Schüle
<uval@rz.uni-karlsruhe.de> wrote:

> hello all,
>
> consider follow code
>
> irb(main):528:0* def abc
> irb(main):529:1> ppp=111
> irb(main):530:1> puts ppp
> irb(main):531:1> yield
> irb(main):532:1> puts ppp
> irb(main):533:1> ppp
> irb(main):534:1> end
> => nil
> irb(main):536:0> abc {}
> 111
> 111
> => 111
> irb(main):537:0> abc { puts ppp }
> 111
> NameError: undefined local variable or method `ppp' for main:Object
> from (irb):537
> from (irb):537:in `abc'
> from (irb):537
> from :0
> irb(main):538:0>
> irb(main):539:0*
> irb(main):540:0* ppp = "OOO"
> => "OOO"
> irb(main):541:0> abc { puts ppp }
> 111
> OOO
> 111
> => 111
> irb(main):542:0>
>
> I am right assuming that all "local" variables in the method abc
> are invisible in the block?
>

Yes. The block captures the scope it is defined in, not the scope it's
called from, i.e. it's a closure.

> I tried a little more
>
> irb(main):544:0* def cba
> irb(main):545:1> ppp = 222
> irb(main):546:1> puts ppp
> irb(main):547:1> yield ppp
> irb(main):548:1> puts ppp
> irb(main):549:1> ppp
> irb(main):550:1> end
> => nil
> irb(main):551:0> cba {}
> 222
> 222
> => 222
> irb(main):552:0> cba {|p|}
> 222
> 222
> => 222
> irb(main):553:0> cba {|p| p = 333}
> 222
> 222
> => 222
> irb(main):554:0> cba {|p| puts p; p = 333}
> 222
> 222
> 222
> => 222
> irb(main):555:0>
>
> if explicitely passed to block ppp is now visible there.
> but seems to be imposible to change the "method local" variable
> ppp in this case.
>

Yes. Ignoring implementation details, the block parameter 'p' is given a
reference to the same object. When you then assign to 'p' that reference
is replaced by a new reference to the object you assigned. Note that this
is only for 'p' - 'ppp' still has the same reference it always had (to the
original object).

The reality is apparently slightly more complex but I believe that for
most practical purposes (including this)you can ignore that.

> the following *does* work
>
> irb(main):557:0* def xxx
> irb(main):558:1> ppp = [1]
> irb(main):559:1> p ppp
> irb(main):560:1> yield ppp
> irb(main):561:1> p ppp
> irb(main):562:1> ppp
> irb(main):563:1> end
> => nil
> irb(main):564:0> xxx {}
> [1]
> [1]
> => [1]
> irb(main):565:0> xxx {|x| }
> [1]
> [1]
> => [1]
> irb(main):566:0> xxx {|x| x[0]=2 }
> [1]
> [2]
> => [2]
> irb(main):567:0>
>
> and I kind of understand why it works
>
> if I change line 566 to
> irb(main):566:0> xxx {|x| x=[2] }
> than it would not work
>

Correct. The original code doesn't actually assign anything to 'x', but
instead calls the []= method on it, which modifies the array's content.
Since both 'ppp' and 'x' reference the same Array instance, your change
makes it out of the block.

In the second case, you _do_ assign to 'x', supplying a new array. 'ppp'
retains it's original value, so the new array is (almost) lost.

Almost, because of course it's not _quite_ lost at that point:

irb(main):001:0> def xxx
irb(main):002:1> ppp = [1]
irb(main):003:1> p ppp
irb(main):004:1> ppp = yield ppp
irb(main):005:1> p ppp
irb(main):006:1> end
=> nil
irb(main):007:0> xxx { |x| x = [2] }
[1]
[2]
=> nil


> the reason I came accross this is following
> I was reading
>
> "
> Parameters to a block may be existing local variables; if so, the new
> value of the variable will be retained after the block completes. This
> may lead to unexpected behavior, but there is also a performance gain to
> be had by using variables that already exist
> "
> and in my understanding all variables defined in a method
> are "local" (C++ background)
>
> If not local what are they considered to be then?
>

They are local. I think that test is referring to this:

irb(main):017:0> def test(arg)
irb(main):018:1> p arg
irb(main):019:1> [1,2,3].select { |arg| arg % 2 == 0 }
irb(main):020:1> p arg
irb(main):021:1> end
=> nil
irb(main):022:0> test("ten")
"ten"
3
=> nil

An interesting aside to this (IMHO) is this:

irb(main):018:0> class Demo
irb(main):019:1> def last=(arg)
irb(main):020:2> (@last ||= []) << arg
irb(main):021:2> end
irb(main):022:1> def all
irb(main):023:2> @last
irb(main):024:2> end
irb(main):025:1> end
=> nil

irb(main):026:0> d = Demo.new
=> #<Demo:0xb7f49a6c>
irb(main):027:0> ['one','two','three'].each { |d.last| }
=> ["one", "two", "three"]
irb(main):028:0> d.last
=> ["one", "two", "three"]

Which I guess illustrates that block arguments are handled by assignment
to the named variable (or method in this case), and should make more sense
of the preceeding example...

Cheers,

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Ross Bamford

1/4/2006 1:09:00 AM

0

Okay, I'm too tired...

On Wed, 04 Jan 2006 00:58:08 -0000, Ross Bamford
<rosco@roscopeco.remove.co.uk> wrote:

> They are local. I think that test is referring to this:
^^^^
That should be 'text'

> An interesting aside to this (IMHO) is this:
>
> irb(main):018:0> class Demo
> irb(main):019:1> def last=(arg)
> irb(main):020:2> (@last ||= []) << arg
> irb(main):021:2> end
> irb(main):022:1> def all
> irb(main):023:2> @last
> irb(main):024:2> end
> irb(main):025:1> end
> => nil
>
> irb(main):026:0> d = Demo.new
> => #<Demo:0xb7f49a6c>
> irb(main):027:0> ['one','two','three'].each { |d.last| }
> => ["one", "two", "three"]
> irb(main):028:0> d.last
^^^^
And that should be:

irb(main):028:0> d.all

> => ["one", "two", "three"]

That'll teach me to refactor in Opera...

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Robert Klemme

1/4/2006 10:11:00 AM

0

Daniel Schüle wrote:

<snip/>

> if I change line 566 to
> irb(main):566:0> xxx {|x| x=[2] }
> than it would not work

Note, that you can use get the return value of the block from yield:

def foo
p yield( 111 )
end

>> foo {|x| x + 10}
121
=> nil

> the reason I came accross this is following
> I was reading
>
> "
> Parameters to a block may be existing local variables; if so, the new
> value of the variable will be retained after the block completes. This
> may lead to unexpected behavior, but there is also a performance gain
> to be had by using variables that already exist
> "
> and in my understanding all variables defined in a method
> are "local" (C++ background)
>
> If not local what are they considered to be then?

They are local. Stress in the setence above must be on "existing". It
means a situation like this:

def get_last(enum)
last = nil
enum.each {|last|}
last
end

>> get_last [1,2,43,3,2,4]
=> 4

This works because "last" is defined before the block. This does not
work:

def get_last(enum)
enum.each {|last|}
last
end

>> get_last [1,2,43,3,2,4]
NameError: undefined local variable or method `last' for main:Object
from (irb):26:in `get_last'
from (irb):28
from :0

IOW, if the variable is defined in the surrounding scope that is the one
used. If it's defined only in the block (either as parameter or in the
body) it's visibility is limited to the block. Note that this is how most
PL do nested scoping.

/* C */
int foo() {
int x;
{
/* x is visible here */
int y = x;
}
/* no y visible here */
}

Note, that the scope of block parameters may change in the future. There
have been lengthy discussions about this but ATM I don't remember the
details.

Kind regards

robert

Daniel Schüle

1/5/2006 2:25:00 AM

0

thx for your replies, this helps

graham

9/1/2010 4:49:00 AM

0


"Kip Williams" <kip@rochester.rr.com> wrote in message
news:lmjfo.105566$xZ2.19265@newsfe07.iad...
>O wrote:
>
>> The "news" per se is actually pretty balanced on Fox, but there's far
>> more opinion programs.
>
> That's not what I see. To them, it's "news" if somebody says something
> awful about [let us say] Obama that they can repeat and repeat and repeat.
>
> "Sources say..." "It is said that..." "Is it the case that...?"
>
> Catapult that propaganda.
>
Apparently, Kruschev remarked to Eisenhower that the US govt and media were
far more proficient in disseminating propaganda to the US population than
the USSR was to the Russians.
My observations ove the years have certainly born out this.
Graham


O

9/1/2010 3:02:00 PM

0

In article
<387bab60-ea71-432f-95d2-40f6af8a7d22@s17g2000prh.googlegroups.com>,
mark <markstenroos@yahoo.com> wrote:

> On Aug 31, 4:54?pm, O <ow...@denofinequityx.com> wrote:
> > In article
> > <b91209aa-4a40-4964-b1a3-c3e1f8fd8...@f42g2000yqn.googlegroups.com>,
> >
> > mark <markstenr...@yahoo.com> wrote:
> > > On Aug 31, 7:04?am, O <ow...@denofinequityx.com> wrote:
> >
> > > > > And EVERY politician looks out for themselves first?
> >
> > > > Yes. Absolutely. ?To think otherwise scoffs in the face of reality.
> > > > Their first mission in office is to make sure they stay in office.
> >
> > > So, that must mean that your first mission at your job is to stay
> > > employed at that job. Not to do a good job or to do something that you
> > > enjoy doing.
> >
> > Are you talking about *my* job, or a politician's job? ?
> >
>
> I'm asking about your job.

In my job, I have to do the best job possible or I'm out the door.
>
> >
> > > Correct?
> >
> > Do you know any politicians? ?I know a few, and there's a couple I wish
> > I'd never met, but they all have one thing in common, and that's the
> > belief that they can't continue to do the good work of the people if
> > they're voted out of office.
>
> And I know a lot of people who aren't politicians who believe that
> they can't continue to do the good work for their customers/people in
> need/et al if they lose their job. Many people have that in common,
> not just politicians.

Not many people get to put off doing their job and spend time making
sure they continue in their job. Almost every Presidential candidate
has another political job they put on hold while they're out
campaigning. Politics is a completely different animal than everyday
jobs.
>
> Have you ever considered that politicians love their jobs for
> altruistic reasons along with the perks and the salary?

I believe most of them think in their heart of hearts that they are the
perfect person for the job, and doing the people's work. That they had
to take some shortcuts to stay in the position means that the people
got to have the best guy in the job.

> In that,
> they're just like everybody else who has a good-paying job they'd like
> to hold onto. That doesn't mean that keeping the job is the be all and
> end all of their existence. neither does it mean that they'll go to
> any lengths to keep it.

They call these people ex-politicians. Have you ever worked for a
political candidate? Read "Primary Colors" or "All the King's Men?" or
even "The Rascal King: The life and times of James Michael Curley?"
It's amazing how intertwined re-election is part of the daily regimen,
how almost every strategem needs a political payoff.

I had a civil service appointment in Massachusetts many years ago.
Those I worked with were all political appointees (one was the nephew
of a state rep who was an alcoholic). They were the ones who had to
stand out on the street corner carrying signs in October. They'd say
to me on Friday "see you tomorrow" and I could say, "Oh no, I'm civil
service."

>
> I'll admit that SOME people are like that, no matter what their job. I
> disagree with your statement that ALL politicians are like that.

There might be a few aldermen in some remote cities somewhere, but if
you're any good as a politician, you'll be fussing over keeping your
seat first. Not the way I think it should be, but the way it is.

-Owen

mark

9/1/2010 3:23:00 PM

0

On Sep 1, 8:01 am, O <ow...@denofinequityx.com> wrote:

>
> > And I know a lot of people who aren't politicians who believe that
> > they can't continue to do the good work for their customers/people in
> > need/et al if they lose their job. Many people have that in common,
> > not just politicians.
>
> Not many people get to put off doing their job and spend time making
> sure they continue in their job.  Almost every Presidential candidate
> has another political job they put on hold while they're out
> campaigning.  Politics is a completely different animal than everyday
> jobs.
>

You've shifted the goalposts by limiting the discussion to
presidential candidates who are only a handful of politicians running
for a very unique position every 4 years (yes, I know they start
campaigning every two years).

Back to MOST politicians - yes, they spend time campaigning and fund
raising, but the bulk of that time is time spent in addition to their
day job in the Congress or wherever. You would have a point if
Congress critters were spending most of their time out fund raising
and campaigning on the taxpayers dime. They're not. And let's not
forget that these Congressional jobs were envisioned very much as part
time jobs when the country was founded. Today, they are full-time plus
gigs.

Almost every Congress critter could make more money working in the
private sector. They become politicians because they want to make a
difference and they have healthy egos and are attracted to power.
Frankly, I think they're all just a little bit "off" to want these
jobs in the first place.

O

9/1/2010 3:39:00 PM

0

In article
<8271fc88-b355-4d45-928a-fec1c5f18fda@z34g2000pro.googlegroups.com>,
mark <markstenroos@yahoo.com> wrote:

> On Sep 1, 8:01?am, O <ow...@denofinequityx.com> wrote:
>
> >
> > > And I know a lot of people who aren't politicians who believe that
> > > they can't continue to do the good work for their customers/people in
> > > need/et al if they lose their job. Many people have that in common,
> > > not just politicians.
> >
> > Not many people get to put off doing their job and spend time making
> > sure they continue in their job. ?Almost every Presidential candidate
> > has another political job they put on hold while they're out
> > campaigning. ?Politics is a completely different animal than everyday
> > jobs.
> >
>
> You've shifted the goalposts by limiting the discussion to
> presidential candidates who are only a handful of politicians running
> for a very unique position every 4 years (yes, I know they start
> campaigning every two years).

No, I haven't. Most Congressmen and Senators take ample time off from
the pursuit to campaign. Many stay in their previous seats while
campaigning for a better seat.
>
> Back to MOST politicians - yes, they spend time campaigning and fund
> raising, but the bulk of that time is time spent in addition to their
> day job in the Congress or wherever.

Hardly. Congress's "recesses" are all about campaigning time. And how
many votes are missed because a representative is out "campaigning?"

> You would have a point if
> Congress critters were spending most of their time out fund raising
> and campaigning on the taxpayers dime. They're not.

A good Congressman is always fund raising and campaigning. It never
stops.

> And let's not
> forget that these Congressional jobs were envisioned very much as part
> time jobs when the country was founded. Today, they are full-time plus
> gigs.

Intent of the Four Fathers? If only they had thought of term limits!
>
> Almost every Congress critter could make more money working in the
> private sector.

Huh? Most Congress critters are already millionaires who want a piece
of more power. What in the world would John Kerry do if he was voted
out of office? Nancy Pelosi? Harry Reid? John McCain!

> They become politicians because they want to make a
> difference and they have healthy egos and are attracted to power.
> Frankly, I think they're all just a little bit "off" to want these
> jobs in the first place.
>
Well, I agree with your last two sentences. :-)

-Owen