Specifying local and external block parameters (that old chestnut)

I’ve cannibalised discussion from the “Bugs” thread. I hope it is a service to
the community to reopen this. The poll on RubyGarden votes “make 'em all
local”, closely followed by “leave it unchanged”. Yet the “problem” keeps
coming up, and the most sensible solution (in my mind) is not represented in
the poll.

I think it makes sense to explicitly mark external variables, as block-local
variables (parameters, in fact) would be the norm.

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external variable,
then one could write

collection.each do |a,:b,c|

end

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the common
case.

I’d like to put a question to the audience :slight_smile: Does anyone actually have a need
to use non-local block parameters? Ever?

Apologies if this can of worms is better left buried.

Cheers,
Gavin

···


Gavin Sinclair Software Engineer
Sydney, Australia Soyabean Software Pty Ltd

I’ve cannibalised discussion from the “Bugs” thread. I hope it is a service to
the community to reopen this. The poll on RubyGarden votes “make 'em all
local”, closely followed by “leave it unchanged”. Yet the “problem” keeps
coming up, and the most sensible solution (in my mind) is not represented in
the poll.

I think it makes sense to explicitly mark external variables, as block-local
variables (parameters, in fact) would be the norm.

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external variable,
then one could write

collection.each do |a,:b,c|

end

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the common
case.

I’d like to put a question to the audience :slight_smile: Does anyone actually have a need
to use non-local block parameters? Ever?

I’ve asked this before but can’t recall any answers. How would one
do the following without non-local block params:

a = [1.1, 3.14, 2.7, 5.15]
sum = 0.0
a.each { |elem| sum += a }

Personally, I like accessing external scope by default. C behaves similiarly:
#include <stdio.h>

int main()
{
int a = 42;
int b = 55;

printf("a: %d b: %d\n", a, b );

{
	int a = 33; /* define a as local scope to this block*/
	printf("a: %d b: %d\n", a, b );
}

}

Gives you

···

On Fri, Oct 04, 2002 at 10:58:07AM +0900, Gavin Sinclair wrote:
a: 42 b: 55
a: 33 b: 55


Alan Chen
Digikata LLC
http://digikata.com

Hi,

I’ve cannibalised discussion from the “Bugs” thread. I hope it is a service to
the community to reopen this. The poll on RubyGarden votes “make 'em all
local”, closely followed by “leave it unchanged”. Yet the “problem” keeps
coming up, and the most sensible solution (in my mind) is not represented in
the poll.

The “solution” changes time to time in my mind. Currently I’m
thinking of the following:

  • variables assigned by “:=” should be local to the block (or
    possibly local to the nearest compound statements).

  • if “:=” assignee is already defined in outer scope, it should be
    warned (no -w needed, probably), and outer variable is shadowed
    hereafter.

  • all local variables in block parameters (e.g. var in |var|) should
    be treated as if they are assigned by “:=”. other types of
    variables in block parameter should be warned.

  • scope of local variables assigned by “=” will be a nearest “body”
    (method body, class body etc.) consistently.

This does not change the appearance of Ruby code much, unlke
solution. It is incompatible to the current syntax, for example,

a = 5
[1,2,3].each{|a| break if a % 2 == 0}
p a

prints “2” now. It will print “5” (with shadowing warning) if we
adopt the changes above. Since it is not compatible, it will not be
available in the near future. Perhaps you have to wait until Rite.

						matz.
···

In message “Specifying local and external block parameters (that old chestnut)” on 02/10/04, “Gavin Sinclair” gsinclair@soyabean.com.au writes:

I think it makes sense to explicitly mark external variables, as
block-local
variables (parameters, in fact) would be the norm.

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external
variable,
then one could write

collection.each do |a,:b,c|

end

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the
common
case.

One problem is that it’s not just a simple variable. It
can be anything that responds to assignment. For example,
an accessor:

0.upto(99) {|frame.scroll| sleep 0.1}

I’d like to put a question to the audience :slight_smile: Does anyone actually have a
need
to use non-local block parameters? Ever?

The above is an example.

Also what if I want the last value(s) of a loop?

x,i = nil
myobj.each_with_index do |x,i|
# process…
break if some_condition
# more processing…
end

last_obj = x
last_index = i

Yes, I could save them off in different variables
right before I did the break:

y,j = nil
myobj.each do |x,i|
#…
if some_condition
y,j = x,i
break
end
#…
end

last_obj, last_index = y,j

Two more variables and much ugliness. No, thanks.

Hal

···

----- Original Message -----
From: “Gavin Sinclair” gsinclair@soyabean.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, October 03, 2002 8:58 PM
Subject: Specifying local and external block parameters (that old chestnut)

I’ve cannibalised discussion from the “Bugs” thread. I hope it is a service to
the community to reopen this. The poll on RubyGarden votes “make 'em all
local”, closely followed by “leave it unchanged”. Yet the “problem” keeps
coming up, and the most sensible solution (in my mind) is not represented in
the poll.

I think it makes sense to explicitly mark external variables, as block-local
variables (parameters, in fact) would be the norm.

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external variable,
then one could write

collection.each do |a,:b,c|

end

I hereby claim authorship of any syntax derived from the use of
the ‘:’ prefix to indicate the scope of block parameters, based on
[ruby-talk:52401]. All rights reserved.

:slight_smile:

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the common
case.

I’d head towards ‘:’. Reason: less typing.
Plus we’re used to having ‘@’ and ‘@@’ to indicate scope (kinda), so it
just makes sense for me.

Local params would surely be more common, but marking them with ‘:’
instead of the external ones has the additional advantage of not
breaking any code out there. The transition could be made very easy if
the current scoping rules are mixed with ‘:’ for a while.

So in
blabla.aaaa do |a,:b|

end

a is local if there’s no variable named ‘a’ previously defined,
otherwise external

b is local even if there’s already ‘b’ in the external scope

bottom line: nothing breaks, ‘:’ forces local

Ruby can issue a warning iff there was no ‘a’ variable before, as this
code would break once the old scoping rules are thrown away and only the
presence or absence of ‘:’ is significant.

I’d like to put a question to the audience :slight_smile: Does anyone actually
have a need to use non-local block parameters? Ever?

They are indeed needed sometimes.

···

On Fri, Oct 04, 2002 at 10:58:07AM +0900, Gavin Sinclair wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Debian is like Suse with yast turned off, just better. :slight_smile:
– Goswin Brederlow

Apologies if this can of worms is better left buried.

Cheers,
Gavin

Following up my own post, I now see that it has been discussed extensively in
the past, nothing has happened, Matz has some plans, and we won’t see any
change until Rite. I have no problem with any of that, so I’ll let this
sleeping dog lie.

Gavin

···

From: “Gavin Sinclair” gsinclair@soyabean.com.au

From: “Gavin Sinclair” gsinclair@soyabean.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, October 03, 2002 8:58 PM
Subject: Specifying local and external block parameters (that old chestnut)

I think it makes sense to explicitly mark external variables, as
block-local
variables (parameters, in fact) would be the norm.

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external
variable,
then one could write

collection.each do |a,:b,c|

end

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the
common
case.

One problem is that it’s not just a simple variable. It
can be anything that responds to assignment. For example,
an accessor:

0.upto(99) {|frame.scroll| sleep 0.1}

So could
0.upto(99) {|:frame.scroll| sleep 0.1}
work?

Look quite good, I think, since we are used to :: as a scoping operator.

I’d like to put a question to the audience :slight_smile: Does anyone actually have a
need
to use non-local block parameters? Ever?

The above is an example.

Quite a nice example too, IMO.

Also what if I want the last value(s) of a loop?

x,i = nil
myobj.each_with_index do |x,i|
# process…
break if some_condition
# more processing…
end

last_obj = x
last_index = i

Yes, I could save them off in different variables
right before I did the break:
[…]
Two more variables and much ugliness. No, thanks.

Hal

I really dislike relying on finishing values like that, because:

  • you have to declare variables beforehand
  • code is harder to understand or be confident that it’s right

Much better, IMO, is

x, i = get_values(myobj)

def get_values(obj)
obj.each_with_index do |x, i|
# process
return x, i if some_condition
# more processing
end
end

Gavin

···

From: “Hal E. Fulton” hal9000@hypermetrics.com

Hi,

0.upto(99) {|frame.scroll| sleep 0.1}

x,i = nil
myobj.each_with_index do |x,i|

process…

break if some_condition

more processing…

end

last_obj = x
last_index = i

Yes, they are problems. With the “solution” described in [ruby-talk:52440],
you have to rewrite them as following respectively.

0.upto(99) {|x| frame.scroll = x; sleep 0.1}

myobj.each_with_index do |x,i|

process…

if some_condition
last_obj = x
last_index = i
break
end

more processing…

end

						matz.
···

In message “Re: Specifying local and external block parameters (that old chestnut)” on 02/10/04, “Hal E. Fulton” hal9000@hypermetrics.com writes:

I’ve asked this before but can’t recall any answers. How would one
do the following without non-local block params:

a = [1.1, 3.14, 2.7, 5.15]
sum = 0.0
a.each { |elem| sum += a }

Shouldn’t it be
a.each { |elem| sum += elem }

Anyway you aren’t using (nor need) non-local block params at all!
You’re simply accessing variables from an external scope, which is OK
(how would we get closures otherwise?) and isn’t the issue we’re to talk about.

The thing is after
a.each { |elem| sum += elem }
elem will be 5.15 iff elem was already in the external scope, otherwise
it isn’t defined.

Compare:
a = [1,2,3,4,5] a = [1,2,3,4,5]
sum = 0 sum = 0
l = 0
a.each { |l| sum += l } a.each { |l| sum += 1 }

here l == 5 # l is undefined here!

With local block parameters, you’d get
a = [1,2,3,4,5]
sum = 0
l = “sdfsdfs”
a.each { |:l| sum += 1 } # I claim this syntax as mine :slight_smile:

l is unchanged here! l == “sdfsdfs”

Personally, I like accessing external scope by default. C behaves similiarly:
#include <stdio.h>

int main()
{
int a = 42;
int b = 55;

printf(“a: %d b: %d\n”, a, b );

{
int a = 33; /* define a as local scope to this block*/
printf(“a: %d b: %d\n”, a, b );
}
}

Gives you
a: 42 b: 55
a: 33 b: 55

In C you can shadow external vars because you must declare them anyway.
In Ruby an assignment to a var creates a new one iff there isn’t already
one with that name.

···

On Fri, Oct 04, 2002 at 11:18:46AM +0900, Alan Chen wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Absolutely nothing should be concluded from these figures except that
no conclusion can be drawn from them.
– Joseph L. Brothers, Linux/PowerPC Project)

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external
variable,
then one could write

collection.each do |a,:b,c|

end

I hereby claim authorship of any syntax derived from the use of
the ‘:’ prefix to indicate the scope of block parameters, based on
[ruby-talk:52401]. All rights reserved.

:slight_smile:

Fair enough. Your royalty cheque is in the mail.

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimise for the
common
case.

I’d head towards ‘:’. Reason: less typing.
Plus we’re used to having ‘@’ and ‘@@’ to indicate scope (kinda), so it
just makes sense for me.

Exactly.

Local params would surely be more common, but marking them with ‘:’
instead of the external ones has the additional advantage of not
breaking any code out there.

I disagree. Marking the external ones rather than internal ones is SO much
more sensible. Seeing a.each do |:x| everywhere is too ugly. Changes have
been made that break code before. How much code would it really break anyway?

The transition could be made very easy if
the current scoping rules are mixed with ‘:’ for a while.

So in
blabla.aaaa do |a,:b|

end

a is local if there’s no variable named ‘a’ previously defined,
otherwise external

This sort of confusion is exactly what we want to get away from.

b is local even if there’s already ‘b’ in the external scope

bottom line: nothing breaks, ‘:’ forces local

Ruby can issue a warning iff there was no ‘a’ variable before, as this
code would break once the old scoping rules are thrown away and only the
presence or absence of ‘:’ is significant.

Gavin

···

From: “Mauricio Fernández” batsman.geo@yahoo.com

Mauricio Fernández wrote:

I hereby claim authorship of any syntax derived from the use of
the ‘:’ prefix to indicate the scope of block parameters, based on
[ruby-talk:52401]. All rights reserved.

Request denied. Previous work proves to be quite similar. Plagarist!
[ruby-talk:5555]

:slight_smile:

Please refrain from using : in smilies, as authorship has been contested
and await legal decision on the matter.

:stuck_out_tongue_winking_eye:

I’d head towards ‘:’. Reason: less typing.
Plus we’re used to having ‘@’ and ‘@@’ to indicate scope (kinda), so it
just makes sense for me.

I like it too, but aparently Matz doesn’t. [ruby-talk:42295]

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

The “solution” changes time to time in my mind. Currently I’m
thinking of the following:

  • variables assigned by “:=” should be local to the block (or
    possibly local to the nearest compound statements).

  • if “:=” assignee is already defined in outer scope, it should be
    warned (no -w needed, probably), and outer variable is shadowed
    hereafter.

Then there must be a way to turn these warnings off, because shadowing
outer scope variables would be quite common IMHO.

  • all local variables in block parameters (e.g. var in |var|) should
    be treated as if they are assigned by “:=”. other types of
    variables in block parameter should be warned.

What about Hal’s
0.upto(99) {|frame.scroll| sleep 0.1}
example?

Accessors would have to be treated differently (introduces a “special
case” in the language).

  • scope of local variables assigned by “=” will be a nearest “body”
    (method body, class body etc.) consistently.

This does not change the appearance of Ruby code much, unlke

It’d make me think of Pascal :-S
Just the thought of such a 'bondage-and-discipline" language could
sicken more than one Rubyist :slight_smile: The “utterly dynamic” vs. “so static
it’s useless” contrast would be too much.

:= does change the appearance more than the admittedly more restricted
‘:’ prefix solution.

solution. It is incompatible to the current syntax, for example,

a = 5
[1,2,3].each{|a| break if a % 2 == 0}
p a

prints “2” now. It will print “5” (with shadowing warning) if we
adopt the changes above. Since it is not compatible, it will not be
available in the near future. Perhaps you have to wait until Rite.

As you say, it also breaks code, which “‘:’ to indicate local” doesn’t.

···

On Fri, Oct 04, 2002 at 11:37:21AM +0900, Yukihiro Matsumoto wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Just go ahead and write your own multitasking multiuser os!
Worked for me all the times.
– Linus Torvalds

From: “Gavin Sinclair” gsinclair@soyabean.com.au

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external variable,
then one could write

collection.each do |a,:b,c|

end

See my note on this syntax in my original reply to Gavin :slight_smile:

One problem is that it’s not just a simple variable. It
can be anything that responds to assignment. For example,
an accessor:

0.upto(99) {|frame.scroll| sleep 0.1}

This works unchanged if you accept ‘:’ as a local scope indicator, only
to be used on variables (not on accesor methods, as it’d be
meaningless), so Ruby would choke on

0.upto(99) {|:frame.scroll| sleep 0.1}

as anyway what you really want is

0.upto(99) {|frame.scroll| sleep 0.1}

I’d like to put a question to the audience :slight_smile: Does anyone actually have a
need
to use non-local block parameters? Ever?

The above is an example.

Also what if I want the last value(s) of a loop?

x,i = nil
myobj.each_with_index do |x,i|
# process…
break if some_condition
# more processing…
end

last_obj = x
last_index = i

Yes, I could save them off in different variables
right before I did the break:

y,j = nil
myobj.each do |x,i|
#…
if some_condition
y,j = x,i
break
end
#…
end

last_obj, last_index = y,j

Two more variables and much ugliness. No, thanks.

One more reason to use ‘:’ to indicate local, so the former code runs
unchanged.

···

On Fri, Oct 04, 2002 at 11:38:46AM +0900, Hal E. Fulton wrote:

----- Original Message -----


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Not only Guinness - Linux is good for you, too.
– Banzai on IRC

chestnut)

From: “Gavin Sinclair” gsinclair@soyabean.com.au

Apologies if this can of worms is better left buried.

Cheers,
Gavin

Following up my own post, I now see that it has been discussed extensively
in
the past, nothing has happened, Matz has some plans, and we won’t see any
change until Rite. I have no problem with any of that, so I’ll let this
sleeping dog lie.

(dog.let_lie while dog.sleep?) >
(horse.beat while horse.dead? ||
can.worms.open ||
(barn.door.open; until barn.empty? {}; barn.door.close))

Apologies for the bad Ruby and the English-specific
attempts at humor.

Hal

···

----- Original Message -----
From: “Gavin Sinclair” gsinclair@soyabean.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Friday, October 04, 2002 3:27 AM
Subject: Re: Specifying local and external block parameters (that old

  * variables assigned by ":=" should be local to the block (or
    possibly local to the nearest compound statements).

What it will do with ?

   b = 12
   2.times do |i|
      b = i
      # ...
      b := i
   end
   p b

the result is `12' or `1'

Guy Decoux

Mauricio Fernández wrote:

I hereby claim authorship of any syntax derived from the use of
the ‘:’ prefix to indicate the scope of block parameters, based on
[ruby-talk:52401]. All rights reserved.

Request denied. Previous work proves to be quite similar. Plagarist!
[ruby-talk:5555]

:slight_smile:

I’m just receiving my first royalty checks. Try to take them from me :sunglasses:
BTW, you’ll have a hard time crawling through Spain’s judicial system
before you can get a single penny back.

Please refrain from using : in smilies, as authorship has been contested
and await legal decision on the matter.

:stuck_out_tongue_winking_eye:

No problem. Clemens Hintze granted me long ago an exclusive, unlimited,
world-wide, royalty-free license to use ‘:’. Talk with your lawyer, for
I suspect you will soon receive a cease and desist letter. }:->

Anyway, I hereby claim authorship of the use of any single-character
prefix or suffix, for which no prior art exists, to indicate scoping in Ruby.

I’d head towards ‘:’. Reason: less typing.
Plus we’re used to having ‘@’ and ‘@@’ to indicate scope (kinda), so it
just makes sense for me.

I like it too, but aparently Matz doesn’t. [ruby-talk:42295]

I’ve just read it but I cannot understand why :-?

···

On Fri, Oct 04, 2002 at 04:47:30PM +0900, Kent Dahl wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Less is more or less more
– Y_Plentyn on #LinuxGER

Hi,

  • if “:=” assignee is already defined in outer scope, it should be
    warned (no -w needed, probably), and outer variable is shadowed
    hereafter.

Then there must be a way to turn these warnings off, because shadowing
outer scope variables would be quite common IMHO.

I’m afraid I won’t give you a way to turn it off. It is “quite
common” in other languages, but it does not mean Ruby must follow.
I believe local variable shadowing is a bad thing.

  • all local variables in block parameters (e.g. var in |var|) should
    be treated as if they are assigned by “:=”. other types of
    variables in block parameter should be warned.

What about Hal’s
0.upto(99) {|frame.scroll| sleep 0.1}
example?

Accessors would have to be treated differently (introduces a “special
case” in the language).

If you read the rule again, you will find the answer. Accessors are
not local variables, so that they will not be treated by “:=” anyway.
Instead, since they are “other types of variables”, you will be warned.

Just the thought of such a 'bondage-and-discipline" language could
sicken more than one Rubyist :slight_smile: The “utterly dynamic” vs. “so static
it’s useless” contrast would be too much.

:= does change the appearance more than the admittedly more restricted
‘:’ prefix solution.

I’m not sure if I get your point. It will surely change the
appearance. But it changes less than the “ solution”.

As you say, it also breaks code, which “‘:’ to indicate local” doesn’t.

Yes. But I feel “‘:’ to indicate local” is ugly. Many (or most)
people want their block parameters “local to the block”. But “‘:’ to
indicate local” requires additional mark for common case. “‘:’ to
indicate external” is better in this sense, but this also breaks
existing code.

						matz.
···

In message “Re: Specifying local and external block parameters (that old chestnut)” on 02/10/04, Mauricio Fernández batsman.geo@yahoo.com writes:

From: “Mauricio Fernández” batsman.geo@yahoo.com

Thus, if ‘a’ and ‘c’ are regular parameters and ‘b’ is an external
variable,
then one could write

collection.each do |a,:b,c|

end

I hereby claim authorship of any syntax derived from the use of
the ‘:’ prefix to indicate the scope of block parameters, based on
[ruby-talk:52401]. All rights reserved.

:slight_smile:

Fair enough. Your royalty cheque is in the mail.

Great! The first time in my life I do earn my very own money! Hehe.

or

collection.each do |a,b,c|
external b

end

I’m not sure which of the above I prefer. One should optimize for the
common
case.

I’d head towards ‘:’. Reason: less typing.
Plus we’re used to having ‘@’ and ‘@@’ to indicate scope (kinda), so it
just makes sense for me.

Exactly.

Local params would surely be more common, but marking them with ‘:’
instead of the external ones has the additional advantage of not
breaking any code out there.

I disagree. Marking the external ones rather than internal ones is SO much
more sensible. Seeing a.each do |:x| everywhere is too ugly. Changes have
been made that break code before. How much code would it really break anyway?

I do agree with you, really. I makes more sense to mark external.
As I’m quite new to Ruby I thought backwards-incompatible changes would
be avoided like plague; but if that’s not much of a concern then it’d
definitively be better to use ‘:’ for locals.

The transition could be made very easy if
the current scoping rules are mixed with ‘:’ for a while.

So in
blabla.aaaa do |a,:b|

end

a is local if there’s no variable named ‘a’ previously defined,
otherwise external

This sort of confusion is exactly what we want to get away from.

During the transition a warning could be issued so ‘:’ is added where
needed.

···

On Fri, Oct 04, 2002 at 04:44:17PM +0900, Gavin Sinclair wrote:

b is local even if there’s already ‘b’ in the external scope

bottom line: nothing breaks, ‘:’ forces local

Ruby can issue a warning iff there was no ‘a’ variable before, as this
code would break once the old scoping rules are thrown away and only the
presence or absence of ‘:’ is significant.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Because I don’t need to worry about finances I can ignore Microsoft
and take over the (computing) world from the grassroots.
– Linus Torvalds

ts decoux@moulon.inra.fr writes:

What it will do with ?

b = 12
2.times do |i|
b = i
# …
b := i
end
p b

And similarly with

b = 12
2.times do |i|
i.times {|b| …}
end

p b #=> ?

I’m not convinced that the scope of a variable is determined by the
operations applied to it. I’d have thought that scope was intrinsic to
the variable itself.

Cheers

Dave

Hi,

  • variables assigned by “:=” should be local to the block (or
    possibly local to the nearest compound statements).

What it will do with ?

b = 12
2.times do |i|
b = i
# …
b := i
end
p b

the result is 12' or 1’

“1”, with warning.

b = 12
2.times do |i|
b = i # assignment to the outer b
# …
b := i # creation of inner b, gives shadowing warning
end
p b

						matz.
···

In message “Re: Specifying local and external block parameters (that old chestnut)” on 02/10/06, ts decoux@moulon.inra.fr writes: