foo || 0 will cause exception but not for himself

  • Thread starter SpringFlowers AutumnMoon
  • Start date
S

SpringFlowers AutumnMoon

if foo is undefined, it will throw exception when referred to... as in
try 1, 2, and 3 below. However, it won't throw exception when assigned
to himself... how is that interpreted?


irb(main):001:0> foo
NameError: undefined local variable or method `foo' for main:Object
from (irb):1:in `Kernel#binding'

irb(main):002:0> foo || 0
NameError: undefined local variable or method `foo' for main:Object
from (irb):2:in `Kernel#binding'

irb(main):003:0> bar = foo || 0
NameError: undefined local variable or method `foo' for main:Object
from (irb):3:in `Kernel#binding'

irb(main):004:0> foo = foo || 0
=> 0

irb(main):005:0> foo
=> 0
 
P

Phrogz

if foo is undefined, it will throw exception when referred to... as in
try 1, 2, and 3 below. However, it won't throw exception when assigned
to himself... how is that interpreted?

irb(main):001:0> foo
NameError: undefined local variable or method `foo' for main:Object
from (irb):1:in `Kernel#binding'

irb(main):002:0> foo || 0
NameError: undefined local variable or method `foo' for main:Object
from (irb):2:in `Kernel#binding'

irb(main):003:0> bar = foo || 0
NameError: undefined local variable or method `foo' for main:Object
from (irb):3:in `Kernel#binding'

irb(main):004:0> foo = foo || 0
=> 0

irb(main):005:0> foo
=> 0

When Ruby says "undefined local variable or method", what it means is
"Hey, I don't know what this is, and I don't know if it's supposed to
be a variable or a method."

When you write "foo = ..." Ruby says, "Ah ha! Foo is supposed to be a
variable. I'll treat it as one."

That's my (somewhat informed) guess anyhow. The determination of the
method/variableness of 'foo' is determined before runtime, when the
lexer/parser is analyzing the program. This is similar to why this
code...
if foo=42
p foo
end
works just fine, but this code:
p foo if foo=42
throws an error. When it first see's foo in the first code sample, it
knows that it is a variable. When it first sees foo in the second code
sample, it doesn't know what it is yet, and throws an error to
indicate its confusion.
 
7

7stud --

SpringFlowers said:
if foo is undefined, it will throw exception when referred to... as in
try 1, 2, and 3 below. However, it won't throw exception when assigned
to himself... how is that interpreted?

irb(main):004:0> foo = foo || 0
=> 0

irb(main):005:0> foo
=> 0

Maybe your Variable/Method Ambiguity thread applies here?


if false
foo = 10
end

puts foo #nil
 
S

SpringFlowers AutumnMoon

7stud said:
if false
foo = 10
end

puts foo #nil

i see...

so after

if false
foo = 10
end

now, bar = foo || 0 will run.

Since for instance methods, the setter method can be foo=()

so how about just a method not inside a class, can it be named "foo=" as
well? if so, how does Ruby know foo=1 is really an assignment or a
method call foo=(1)?

Ruby doesn't seem to like "foo=" as a method:

def foo=(i)
p "ha", i+1
end

def bar?(i)
i % 10
end

p foo=(1)

p foo

p bar?(22)


it will print out

1
1
2
 
P

Phrogz

so how about just a method not inside a class, can it be named "foo=" as
well? if so, how does Ruby know foo=1 is really an assignment or a
method call foo=(1)?

Ruby doesn't seem to like "foo=" as a method:

self.foo = 10
 
P

Phrogz

def foo=(val)
"hello"
end

puts self.foo = 10 #10

Er, what's your point? Methods whose names end with a '=' character
always return the value 'assigned' to them, not the last expression in
the method. How is that relevant to this discussion of how to invoke
them, and the scope and determinatino of variables versus methods?
 
R

Rick DeNatale

Er, what's your point? Methods whose names end with a '=' character
always return the value 'assigned' to them, not the last expression in
the method. How is that relevant to this discussion of how to invoke
them, and the scope and determinatino of variables versus methods?

Actually, it's not that, it's the way assignments get parsed/compiled:

irb(main):001:0> class Foo
irb(main):002:1> def x
irb(main):003:2> @x
irb(main):004:2> end
irb(main):005:1> def x=(val)
irb(main):006:2> @x = val
irb(main):007:2> "Surprise"
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> f = Foo.new
=> #<Foo:0x7a1fc>
irb(main):011:0> f.x=2
=> 2
irb(main):012:0> f.__send__:)x=, 3)
=> "Surprise"
irb(main):013:0> f.x
=> 3
 

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

No members online now.

Forum statistics

Threads
474,264
Messages
2,571,323
Members
48,008
Latest member
KieraMcGuf

Latest Threads

Top