I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
but is it true that the "a" is not global to begin with....
but then, isn't the "a" inside the block more local than the "a"
outside?
like in Pascal, i think there can be nested functions and therefore,
there will be local and then "local that is more local" than the outer
local.
--
Posted via http://www.ruby-forum.com/.
I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
Also, I think I recall reading a post by Matz somewhere where he
shouldered the blame for that "feature" and said it was a design
mistake.
I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
a = 1
p a
1.upto(10) {|a| p a}
p a
--------------
E:\>ruby test_iterator.rb
1
2
3
4
5
6
7
8
9
10
a is changed!
but is it true that the "a" is not global to begin with....
but then, isn't the "a" inside the block more local than the "a"
outside?
a is local, not global. The semantics of block parameters is
assignment semantics:
>a>
basically means "a = ...", in the same scope as the scope in which the
block is created. Blocks are different in that respect from methods,
and the || notation (instead of (), as in methods) is a good reminder
that they're not the same. (Not that || specifically implies
assignment semantics, but it's a reminder that there's a difference.)
David
···
On Sun, 14 Oct 2007, SpringFlowers AutumnMoon wrote:
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
On Oct 14, 2007, at 8:42 AM, SpringFlowers AutumnMoon wrote:
I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
a = 1
p a
1.upto(10) {|a| p a}
p a
--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama
On 10/14/07, SpringFlowers AutumnMoon <summercoolness@gmail.com> wrote:
I thought a iterator with a block is like an nameless function call...
so if it is a function call, the parameter is local.
but for the following, the output is surprising:
but is it true that the "a" is not global to begin with....
but then, isn't the "a" inside the block more local than the "a"
outside?
like in Pascal, i think there can be nested functions and therefore,
there will be local and then "local that is more local" than the outer
local.
--
Posted via http://www.ruby-forum.com/\.
I thought a iterator with a block is like an nameless function call...
Here's another example(a modification of the example found in pickaxe2,
p 106):
if false
data = "hello"
end
(1..3).each {data = "goodbye"}
puts data
--output:--
goodbye
That is equivalent to Java's call by value--but using references and C++
reference semantics, and the flat scope is converted to spheric scope
with assignment semantics applying throughout any call by value passing.
I should amend that by noting that it's a "one-way valve": if the
variable exists before the block is created, the scope is flat,
whereas if the variable doesn't exist yet, it also doesn't exist when
the block exits.
In other words, the local scope enters the block, from the left, so to
speak, bringing all its bindings with it; and it exits from the right
with only those bindings, which may or may not have been altered
during their time in the block.
David
···
On Mon, 15 Oct 2007, David A. Black wrote:
a is local, not global. The semantics of block parameters is
assignment semantics:
>a>
basically means "a = ...", in the same scope as the scope in which the
block is created.
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
No it's not. no matter what 'spheric scope' means.
Blocks are closures, they are NOT functions/methods.
In the example the variable 'data' in the block is the same variable
as 'data' in data = 'hello'
In that sense this is no different than
if false; data = 'hello';end
data = 'goodbye'
The variable definition is lexical, so it doesn't matter that the
data='hello' statement didn't get executed, it's the fact that the
parser saw it which caused it to be defined.
And note that if you JUST had
1.times {a = "goodbye"}
with no prior definition of a in the scope, you'd get a NameError when
you ran it because a is undefined, and Ruby 1.8 doesn't allow new
locals to be defined within a block.
Ruby 1.9 has a feature marked EXPERIMENTAL which allows block locals
to be defined by listing them in the |'s preceded by a ; after any
block arguments. This might or might not survive.
···
On 10/15/07, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
SpringFlowers AutumnMoon wrote:
>
> I thought a iterator with a block is like an nameless function call...
>
Here's another example(a modification of the example found in pickaxe2,
p 106):
if false
data = "hello"
end
(1..3).each {data = "goodbye"}
puts data
--output:--
goodbye
That is equivalent to Java's call by value--but using references and C++
reference semantics, and the flat scope is converted to spheric scope
with assignment semantics applying throughout any call by value passing.
I don't know what software install Ruby 1.9 on my computer
C:\Users\Mike\ruby-1.9.0-20060415-i386-mswin32
This is a very old version of Ruby 1.9. Please don't forget that Ruby
1.9(.0) is still an experimental version, that will move towards the
final Ruby 1.9.1 in December 2007 (I hope "December 2007" is the correct
date).
Well, that's kind of the point of blocks, isn't it? They close over
any vars that are currently in scope. Methods on the other hand have
their own scope. I guess it could be confusing if you thought methods
and blocks were the same thing...but, um, they're not.
Pat
···
On 10/14/07, SpringFlowers AutumnMoon <summercoolness@gmail.com> wrote:
Pat Maddox wrote:
> This seems to me along the same lines as
>
> a = 1
> if true
> a = 10
> end
> p a # => 10
>
> Which certainly is not surprising or unwelcome.
On Mon, 15 Oct 2007, SpringFlowers AutumnMoon wrote:
Pat Maddox wrote:
This seems to me along the same lines as
a = 1
if true
a = 10
end
p a # => 10
Which certainly is not surprising or unwelcome.
when compared to the following it is surprising:
a = 1
p a
def foo(a)
p a
end
for i in 1..10
foo(i)
end
p a
------------------
E:\>ruby test_iterator2.rb
1
2
3
4
5
6
7
8
9
10
1
There's no relation or connection between the two. The def keyword
always starts a new local scope; the if keyword doesn't. There's no
reason to expect them to behave the same way as each other, as they
serve entirely different purposes.
David
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
Yes, the def syntax specifically doesn't take the caller binding, AFAIK.
If you intend having methods access variables local to where they are
defined, just use define_method, which takes a block, with all of its
peculiarities, like taking the caller binding along with its local
variables.
There's no relation or connection between the two. The def keyword
always starts a new local scope; the if keyword doesn't. There's no
reason to expect them to behave the same way as each other, as they
serve entirely different purposes.
So in a way, think of a code block like a "if" statement? (no new local
scope)
Come to think about it, since
[1,2,3,4,5].each {|a| p a}
is equivalent to
for a in [1,2,3,4,5]
p a
end
so the "for" version clearly doesn't have a new scope for "a".
But in the newest Ruby 1.9, they are not equivalent any more?
···
On Mon, 15 Oct 2007, SpringFlowers AutumnMoon wrote:
So in a way, think of a code block like a "if" statement? (no new local
scope)
Come to think about it, since
[1,2,3,4,5].each {|a| p a}
is equivalent to
for a in [1,2,3,4,5]
p a
end
so the "for" version clearly doesn't have a new scope for "a".
But in the newest Ruby 1.9, they are not equivalent any more?
No, they aren't the same even in Ruby 1.8.x either. With the do...end or
{...} syntax, any variables assigned in the block, but inexisting at the
point of the definition of the block, are actually local to the block.
AFAIK, in 1.9, the formal parameters of the block, specified between
's, are considered unconditionally block-local *too*. In 1.8.x, those
are treated like any other local variables in the block: they refer to
the same as the enclosing block if pre-existing, and refer to
block-local variables otherwise.
There's no relation or connection between the two. The def keyword
always starts a new local scope; the if keyword doesn't. There's no
reason to expect them to behave the same way as each other, as they
serve entirely different purposes.
So in a way, think of a code block like a "if" statement? (no new local
scope)
I think the best thing is to learn about blocks as blocks, and don't
worry too much about how much they are or aren't similar to other
things. A block has the variables from the local scope in which it was
created, and can also create its own variables, but the ones it
creates exist only inside the block. An if statement is truly flat
with regard to its local scope.
David
···
On Mon, 15 Oct 2007, SpringFlowers AutumnMoon wrote:
On Mon, 15 Oct 2007, SpringFlowers AutumnMoon wrote:
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!