----- Original Message -----
From: Wayne Blair <wayne.blair / relian.com>
To: ruby-talk ML <ruby-talk / ruby-lang.org>
Sent: Thursday, May 31, 2001 10:18 PM
Subject: [ruby-talk:16114] Re: Strange idea... exporting from a scope


> Hi Hal,
>
> Maybe I'm missing something (like I have no idea what the block problem
is),
> but why wouldn't you just declare the variable in the outer scope then set
> it from inside the block:
>
> my_var = nil
> my_method do |x,y,z|
>    # ...
>    my_var = 123
>    #...
> end
> puts my_var      # 123

Hi Wayne...

I always get confused by this, and I'm a fool for answering this
email at nearly 1 a.m. my time... my neurons are firing very
sluggishly.

Here is my summary of the block problem. (I'm likely missing
some points.)

1. Intuition (for many people) says that the entities in the
"parameter" list (which really isn't a parameter list, right?)
are local to the block.

2. Their intuition is wrong. If Ruby sees a variable in the list
that already exists, it will use the existing one.

3. Some people at some times hate this. They don't want a
variable trounced just because they used a variable of the
same name in an innocent-looking context. They would like
to see these variables all become block-local by default.

4. Other people at other times would hate the default-block-local
behavior. They depend on the existing behavior so as not to
have to create unnecessary variables and do extraneous
assignments.

  item = nil
  x.each do |item|
    if condition(item)
        break
    end
  end

  puts item    # This one caused the failure
  # item = nil above is needed, or item is unknown here

5. I still favor the symbol idea -- if a param is a symbol, then it
refers to the outer scope; if not, it's block-local. This will still
break old code, but I think it is more intuitive than the reverse
(which would not break old code). And if it's a symbol, and the
variable doesn't exist yet, then create it.

  x = 5                            # and y doesn't exist
  my_meth do | x, :y |
    x = 6
    y = 7
  end

  puts x              # 5  (unchanged)
  puts y              # 7  (new var)

Not *all* code would be broken anyhow... only that which
depended on this feature. If you're not doing an "implicit import
and export" of a variable, you're in good shape.

6. I suppose the only thing that the export method would save you
is having to define a variable before the block. That reminds me
too much of a variable declaration in this case (and Ruby does
not have those, as such).

The reason is that we expect "the stuff the block does" to be
understandable from reading the block. But its behavior is
radically changed by something *before* the block. (Yes, I know
that all locals are available inside the block -- that's not my point --
the point is that I just forgot the point.)

Anyway, I guess #5 above is still my favorite solution... but I was
intrigued by the idea of a variable being "exported" from a scope.

Thanks for replying,
Hal