Weird variable scope behaviour

I just wrote some code that shouldn’t have worked, in my estimation, but
it did, anyway. While this was a pleasant surprise, I prefer to
understand
why things don’t work than to wonder why they did work…

What was happening is this situation, here:

if false
variable = true
end

if variable
#do something
end

To my surprise, this is okay!  Even though the code in the first

if-clause doesn’t get run, the variable in the clause gets created,
anyway…
Now, I’m pretty sure this is expected behaviour. What I’m wondering
is
how people feel about this. This behaviour makes me feel uneasy. If
I’m
using a variable that hasn’t been deliberately created then I’d rather
have
the interpreter complain that I haven’t created the variable, as
planned,
than to be confused as to why my variable is nil.
I’m very interested to hear other opinions on the subect. Anyone
care
to comment?
Thank you…

Just Another Victim wrote:

if false
variable = true
end

if variable
#do something
end

To my surprise, this is okay!  

What do you mean by “okay”? Does the following not work as you would
expect:

if false
x = 10
end

if x
puts “yep”
else
puts “nope”
end

Also, see here:

http://www.ruby-forum.com/topic/124638#new

7stud – wrote:

What do you mean by “okay”?

Ok, I see:

This behaviour makes me feel uneasy. If
I’m
using a variable that hasn’t been deliberately created then I’d rather
have
the interpreter complain that I haven’t created the variable, as
planned,
than to be confused as to why my variable is nil.

7stud – wrote:

Does the following not work as you would
expect:

if false
x = 10
end

if x
puts “yep”
else
puts “nope”
end

Ah. I see what you are concerned about:

if y
puts “yep”
else
puts “nope”
end

undefined local variable or method `y’ for main:Object (NameError)

On Sep 22, 4:32 pm, “Just Another Victim of the Ambient M.”
[email protected] wrote:

if variable
than to be confused as to why my variable is nil.
I’m very interested to hear other opinions on the subect. Anyone care
to comment?
Thank you…

I understand the behavior, and I’ve learned to live with it. But (as
I’ve noted on numerous occassions) I really don’t like the reverse
side effect, that you can’t write:
p foo if foo=true
even though you can write:
if foo=true then p foo; end

That two statements that are semantically identical should result in
different behavior when foo has not previously been assigned a value
is an unfortunate side effect/tradeoff of the implementation details
and choices.

I accept it in the same way I accept that arrays and hashes have, in
some cases, traded purity for speed. It ain’t perfect, but it’s what
we got.

“Phrogz” [email protected] wrote in message
news:[email protected]

is an unfortunate side effect/tradeoff of the implementation details
and choices.

I accept it in the same way I accept that arrays and hashes have, in
some cases, traded purity for speed. It ain’t perfect, but it’s what
we got.

I'm interested in to what you're referring, here.  How was purity of

arrays and hashes compromised for speed?
Thank you…

On Sep 23, 8:05 pm, “Just Another Victim of the Ambient M.”
[email protected] wrote:

“Phrogz” [email protected] wrote in message

I accept it in the same way I accept that arrays and hashes have, in
some cases, traded purity for speed. It ain’t perfect, but it’s what
we got.

I'm interested in to what you're referring, here.  How was purity of

arrays and hashes compromised for speed?

Things like the fact that Hash and Array literals don’t call their
#initialize method, or that all Array methods that fetch values from
the array don’t fall back on a single method that one can intercept or
override.

“7stud --” [email protected] wrote in message
news:[email protected]

puts "yep"

puts “nope”
end

undefined local variable or method `y’ for main:Object (NameError)

I'm not sure, exactly, what I'm concerned about but I can give you 

some
clues.
It’s a little weird that the above code with variable y results in a
name error but the previous example with variable x simply results in a
nil
object reference. It seems as if they should both result in a nil
object
reference or they should both result in a name error, rather than being
inconsistent with each other.
The most pragmatic example of a problem, that I can think of, is a
situation where you have a bug that’s immediately caused by a variable
that’s unexpectedly nil. Now, you have to trace back the life of the
variable, which can traverse many different scopes, to hopefully
discover
that there was an execution path that didn’t initialize the variable.
Instead, wouldn’t it have been nice if the interpreter simply told you,
at
the variable’s first use, that it didn’t exist 'cause it wasn’t
initialized?
Now that I put it this way, I think I see how its current behaviour
is
an implementation detail, done for increasing speed, leaking through the
interface…