New Local Variable Scope rule

T

ts

R> Why would we have anything defined here although both blocks are not
R> executed in this example? Slowly I'm loosing grips here... A summary was
R> definitely in order.

because ruby don't need to execute a block to see local variables :)


Guy Decoux
 
M

Mark Hubbart

I wish someone would summarize them. The inevitable difficulty of
doing so would demonstrate what to my mind is obvious: the complexity
is getting way out of hand!

I've forgotten what the motivation for splitting apart a seemingly
unified concept is.

I agree... I can't help but think that these things could be simplified
and condensed back into a unified concept. But, right now we have: Proc
objects, lambdas, and code blocks. And they behave differently in
things like Class.new, define_method, instance_eval, etc...

What if there were different attributes of blocks that could be
modified, so that all the different usages could be combined? ie,
Proc#uses_locals, Proc#checks_arity, etc.

This is just a kinda spur of the moment solution; there is probably a
big hole or two in the idea. Anyone with more knowledge about Ruby's
guts care to comment?

cheers,
--Mark
 
D

David Alan Black

Hi --

ts said:
D> I admit I'm confused by this. Is 'local' being introduced? And if
D> |a| is a block variable, isn't it local to the block anyway?

[ruby-talk:63199]

D> I'm not sure what you mean. Do you mean what would I do if I were
D> designing Ruby 2.0,

yes,

D> or what do I think Matz will have them do? I
D> don't know, since I still don't know the answer to the above (whether
D> Proc and lambda will be different in this respect). I think maybe you
D> think that I know, but I don't :)

If you introduce a difference between Proc and lambda, what do you do
with the examples that I've given ?

Thread will work like Proc or like lambda ?

Every code block will work (I assume!) like every other code block.
(Otherwise learning how to use blocks would be like learning irregular
verbs.) So if Thread.new takes a block, that's exactly the same as
any other method taking a block.

But that may or may not mean that Proc objects and lambdas, neither of
which (as I understand it) are the same thing strictly speaking as
code blocks (the thing that would be called a Block if there were a
Block class :) behave the same as each other.

Going back to the original point (more or less): I'm just a little
perplexed by the whole idea of closures (blocks, Procs, lambdas)
having this compile-time effect on local variables in their context of
creation.


David
 
T

ts

D> Going back to the original point (more or less): I'm just a little
D> perplexed by the whole idea of closures (blocks, Procs, lambdas)
D> having this compile-time effect on local variables in their context of
D> creation.

Well, actually this is at compile time that ruby make the difference
between local, block-local variable and method call.

If I've well understood, in 2.0 this is not changed : the only difference
is how ruby make the difference between local and block-local variable.

Now the worst case is perhaps this

svg% cat b.rb
#!/usr/bin/ruby
thr = []
5.times do |i|
thr << Thread.new do
a = i
Thread.stop
puts a
end
end

thr.each {|t| t.run }
svg%

svg% b.rb
0
1
2
3
4
svg%

I'm not sure but I think that for 2.0 all threads will give the same
result.

Do these constructs are really frequent ? I don't know.

The best way do know this is to modify your personnal version of ruby and
use it : you can have surprise :)))


Guy Decoux
 
D

David Alan Black

Hi --

ts said:
D> Going back to the original point (more or less): I'm just a little
D> perplexed by the whole idea of closures (blocks, Procs, lambdas)
D> having this compile-time effect on local variables in their context of
D> creation.

Well, actually this is at compile time that ruby make the difference
between local, block-local variable and method call.

If I've well understood, in 2.0 this is not changed : the only difference
is how ruby make the difference between local and block-local variable.

That's my understanding too (see above). I'm just not entirely
comfortable with it.
Now the worst case is perhaps this

svg% cat b.rb
#!/usr/bin/ruby
thr = []
5.times do |i|
thr << Thread.new do
a = i
Thread.stop
puts a
end
end

thr.each {|t| t.run }
svg%

svg% b.rb
0
1
2
3
4
svg%

I'm not sure but I think that for 2.0 all threads will give the same
result.

I assume so; it's like your other example, where 2.0 behaves the way
pre-2.0 does with "a = nil" before the block. To avoid it I guess
you'd have to do:

... Thread.new do |a| # etc.

to create a new 'a' each time.


David
 
C

Charles Comstock

David said:
Hi --

D> Going back to the original point (more or less): I'm just a little
D> perplexed by the whole idea of closures (blocks, Procs, lambdas)
D> having this compile-time effect on local variables in their context of
D> creation.

Well, actually this is at compile time that ruby make the difference
between local, block-local variable and method call.

If I've well understood, in 2.0 this is not changed : the only difference
is how ruby make the difference between local and block-local variable.


That's my understanding too (see above). I'm just not entirely
comfortable with it.

Now the worst case is perhaps this

svg% cat b.rb
#!/usr/bin/ruby
thr = []
5.times do |i|
thr << Thread.new do
a = i
Thread.stop
puts a
end
end

thr.each {|t| t.run }
svg%

svg% b.rb
0
1
2
3
4
svg%

I'm not sure but I think that for 2.0 all threads will give the same
result.


I assume so; it's like your other example, where 2.0 behaves the way
pre-2.0 does with "a = nil" before the block. To avoid it I guess
you'd have to do:

... Thread.new do |a| # etc.

to create a new 'a' each time.


David

Feels awk-ish to me, the way you have to declare local variables by
stuffing them in the parameter list. And awk doesn't have the easy
ability to convert a list into a parameter list. So what do you do if
you have a parameter list you don't know how long it will be but you
still need local variables?

This method bothers me considerably. It may make it easier for short
code, but I really don't mind stuffing a "var = nil" before doing
something in a block, that to me seems logical. Kind of annoying, but
logical.

Charlie
 
T

ts

D> ... Thread.new do |a| # etc.

or like this

local do |a|

and you see immediately an advantage : you can cut/paste your block and
ruby will do always the same thing because the block-local variable is
directly associated with its block via ||

This is not true with 1.8

Guy Decoux
 
D

David Alan Black

Hi --

ts said:
D> ... Thread.new do |a| # etc.

or like this

local do |a|

and you see immediately an advantage : you can cut/paste your block and
ruby will do always the same thing because the block-local variable is
directly associated with its block via ||

This is not true with 1.8

Is a 'local' keyword being introduced in 2.0? I can't find mention of
it.


David
 
T

ts

D> Is a 'local' keyword being introduced in 2.0? I can't find mention of
D> it.

[ruby-talk:97250] which give reference to [ruby-talk:63199] :)

Guy Decoux
 
D

Dave Brown

: > Is a 'local' keyword being introduced in 2.0? I can't find mention of
: > it.
:
: All local would be is ...
:
: def local
: yield
: end

Hrmm. Not QUITE. It complained at me when I tried that.

irb(main):001:0> def local;yield;end
=> nil
irb(main):002:0> local do |x| x=32;p x;end
(irb):2: warning: multiple values for a block parameter (0 for 1)
from (irb):1
32
=> nil

A slight variation on that though...

irb(main):007:0> def local(&block);yield block;end
=> nil
irb(main):008:0> local do |x| x=32; p x; end
32
=> nil
irb(main):009:0> x
NameError: undefined local variable or method `x' for main:Object

That works nicely.

--Dave
 
M

Mauricio Fernández

: > Is a 'local' keyword being introduced in 2.0? I can't find mention of
: > it.
:
: All local would be is ...
:
: def local
: yield
: end

Hrmm. Not QUITE. It complained at me when I tried that.

[ruby-talk:64791]

I'm not sure |a| will accept an arbitrary num. of args. in the future
(you might need |*a|).
A slight variation on that though...

irb(main):007:0> def local(&block);yield block;end

I don't think this is doing what you think it is doing ;-)
#<Proc:0x401f8ee0@(irb):2>
=> nil

for the matter,
(irb):3: warning: method redefined; discarding old local
=> nil1
=> nil=> nil

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

i dont even know if it makes sense at all :) This is an experimental patch
for an experimental kernel :))
-- Ingo Molnar on linux-kernel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top