[#6363] Re: rescue clause affecting IO loop behavior — ts <decoux@...>

>>>>> "D" == David Alan Black <dblack@candle.superlink.net> writes:

17 messages 2000/11/14
[#6367] Re: rescue clause affecting IO loop behavior — David Alan Black <dblack@...> 2000/11/14

Hello again --

[#6582] best way to interleaf arrays? — David Alan Black <dblack@...>

Hello --

15 messages 2000/11/26

[#6646] RE: Array Intersect (&) question — Aleksi Niemel<aleksi.niemela@...>

Ross asked something about widely known and largely ignored language (on

23 messages 2000/11/29
[#6652] RE: Array Intersect (&) question — rpmohn@... (Ross Mohn) 2000/11/29

aleksi.niemela@cinnober.com (Aleksi Niemel) wrote in

[#6723] Re: Array Intersect (&) question — Mathieu Bouchard <matju@...> 2000/12/01

> >Use a hash. Here's code to do both and more. It assumes that

[#6656] printing/accessing arrays and hashes — raja@... (Raja S.)

I'm coming to Ruby with a Python & Common Lisp background.

24 messages 2000/11/30

[ruby-talk:6671] Re: each/for binding confusion and resolution

From: Clemens Hintze <c.hintze@...>
Date: 2000-11-30 09:10:10 UTC
List: ruby-talk #6671
You wrote:

(...)

> In essence, one problem I had came down to the following:
> 
>     procs = []
>     for v in [1, 2]
> 	  procs << proc { v }
>     end
>     procs.collect { |p| p.call }	-> [2, 2]
> 
> I was hoping for [1, 2].

(...)

>     procs = []
>     [1, 2].each { |v|
> 	  procs << proc { v }
>     }   
>     procs.collect { |p| p.call }	-> [1, 2]

(...)

> So now I understand enough to get my original code to work.  I am
> left with a few questions:
>     Is my analysis correct?  Does <each> create a new binding every
>     time through the loop?

Yes and no! The 'problem' with for vs. each is very easy to
understand. In reality it is more a statement vs. block thingy. The
'for' statement will not create any new scope, as it is part of the
current execution environment as you would also expect in other
languages like C/C++ or such.

A block, however, CAN introduce a new scope. A block is not only a
syntax for grouping statement like in C/C++/Pascal and such. A block
IS an object. It is not *really* part of the current context, but
creating a new context which refers to the current one. In that new
context, whenever a variable is assigned first time (means created)
the variable will be created local to the current context. But pay
attention: if the variable already exists in the 'parent' context,
THAT variable will be used and no new variable will be created.

To make you functional example misbehaving: ;-)

    v = nil                            # THIS is the difference!
    procs = []
    [1, 2].each { |v|
	  procs << proc { v }
    }   
    procs.collect { |p| p.call }	-> [2, 2]

The block creates a new context referring to the old one as parent!
But as the variable 'v' is already used the new context WILL NOT get
another variable 'v' here; the old one is reused.

Another hint I would advise you: think of '|...|' as parameter marker
for blocks. Every name in-between '|...|' will be use to assign a
block parameter to a variable with that name during block invocation. 
This assignment works as I have described above (re-use/creation
wise).

>     Is this the right way to fix the problem?  It apparently imposes
>     some overhead in that there is a binding stored with each proc,

Yes! But the binding is stored anyway! Blocks will refer to the parent
context, whether you use it or not, AFAIK!

>     and a binding resolution occurs each time the proc is called.  I
>     think I'd be happier to have a way of specifying that I want the
>     _value_ of "v", analogous to the #{} notation in double-quoted
>     strings.  Is there a straightforward way to fix the code that
>     uses a <for> loop, rather than an <each> iterator?  I don't need
>     it, but it would be interesting to know of alternate solutions.

POLS. As you already mentioned: use #{} ;-)

  procs = []
  for v in [1, 2]
    procs << eval("proc { #{v} }")
  end
  procs.collect { |p| p.call }     -> [1, 2]

'eval' is your friend here. But beware: eval may be dangerous under
some circumstances.

> Ruby kicks ass.  Thanks for any help.

Good and truly spoken :-)

HTH,
\cle

In This Thread

Prev Next