"def nothing=(data) false end" returns 'data' instead of 'false'

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

Hi, this is really annoying:

---------------------
class MyTest
def nothing=3D(data)
return false
end
end

test=3DMyTest.new

test.nothing=3D123
=3D> 123

test.send("nothing=3D",123)
=3D> false
---------------------

Why does "test.nothing=3D123" return 123 instead of false ???

Thanks a lot for any clarification.

--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 
K

Ken Bloom

Hi, this is really annoying:

---------------------
class MyTest
def nothing=(data)
return false
end
end

test=MyTest.new

test.nothing=123
=> 123

test.send("nothing=",123)
=> false
---------------------

Why does "test.nothing=123" return 123 instead of false ???

Thanks a lot for any clarification.


Because when you use test.nothing=123, you're not directly calling the
method -- you're acutally doing an assignment operator, which calls the
nothing= internally. The assignment operator always returns the value on
the right side, and the return value from nothing= is ignored.

--Ken
 
I

Igor Pirnovar

Ken said:
Because when you use test.nothing=123, you're not directly calling the
method -- you're acutally doing an assignment operator, Precisely!

def x= ; ... end
is really assignment operator definition and not a normal message,
method or a function if you like. Take away the equal sign and it will
behave like you'd expect it. This does not mean that there is no bug
here, however, it is highly unlikely that anyone who uses the assignment
definition properly would ever see it. The bug showed up in a slightly
incorrect use of this feature and I do believe should be fixed if for
nothing else but for the sake of completeness, when all far more serious
bugs are fixed ;)

+-----------------------+
| class MyTest |
| def nothing(data) |
| return false |
| end |
| end |
| o = MyTest.new |
| puts o.nothing=(123) |
|-----------------------|
|OUTPUTS: false |
+-----------------------+
 
7

7stud --

Iñaki Baz Castillo said:
Thanks a lot for any clarification.

As a recent thread pointed out: "that's just the way it is". An equals
method just returns its argument:

class Person
def name=(val)
@name = val
end

def name
@name
end
end

p = Person.new
p.name = "Alice"
puts p.name #Alice

class Person

def age=(val)
@age = val
return 20
end

def age
@age
end
end

p.age = 22
puts p.age #22

puts p.age = 30 #30

Presumably, "that's the way it i" so that when you write something like:

x = p.age = 40

you can know that x will equal 40, although somewhat paradoxically you
can't know that p.age will equal 40:

class Person
def age=(val)
@age = val * 0.80
return "hello"
end
end

x = p.age = 40
puts x #40
puts p.age #32.0
 
I

Igor Pirnovar

7stud said:
As a recent thread pointed out: "that's just the way it is". An equals
method just returns its argument:
Exactly!

However, it is arguable if current behaviour is really a bug, assignment
is supposed to always return what it is assigned to. But on the other
hand one may have a circumstance when assigning something to a thing
like a black hole, for instance, should always return false, and that is
where true == false as someone in another discussion here was
flabbergasted, when I brought up such a possibility.
 
I

Iñaki Baz Castillo

2009/2/26 Igor Pirnovar said:
is really assignment operator definition and not a normal message,
method or a function if you like. Take away the equal sign and it will
behave like you'd expect it. This does not mean that there is no bug
here, however, it is highly unlikely that anyone who uses the assignment
definition properly would ever see it. The bug showed up in a slightly
incorrect use of this feature and I do believe should be fixed if for
nothing else but for the sake of completeness, when all far more serious
bugs are fixed ;)

=C2=A0+-----------------------+
=C2=A0| =C2=A0class MyTest =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
=C2=A0| =C2=A0 =C2=A0def nothing(data) =C2=A0|
=C2=A0| =C2=A0 =C2=A0 =C2=A0return false =C2=A0 =C2=A0 |
=C2=A0| =C2=A0 =C2=A0end =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|
=C2=A0| =C2=A0end =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|
=C2=A0| =C2=A0o =3D MyTest.new =C2=A0 =C2=A0 =C2=A0 |
=C2=A0| =C2=A0puts o.nothing=3D(123) |
=C2=A0|-----------------------|
=C2=A0|OUTPUTS: false =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
=C2=A0+-----------------------+


ok, thanks to all for the explanation.


--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 
7

7stud --

7stud said:
As a recent thread pointed out: "that's just the way it is". An equals
method just returns its argument:

...which had nothing to do with the op's question. Sorry, I answered a
question that only existed in my mind.
 
7

7stud --

Igor said:
The bug showed up in a slightly
incorrect use of this feature and I do believe should be fixed if for
nothing else but for the sake of completeness, when all far more serious
bugs are fixed ;)

+-----------------------+
| class MyTest |
| def nothing(data) |
| return false |
| end |
| end |
| o = MyTest.new |
| puts o.nothing=(123) |
|-----------------------|
|OUTPUTS: false |
+-----------------------+

I get the expected output with ruby 1.8.2:

class A
def nothing(data)
return "hello"
end
end

a = A.new
puts a.nothing=(123)

--output:--r1test.rb:51:
undefined method `nothing=' for #<A:0x25364> (NoMethodError)
 
R

Ryan Davis

Because when you use test.nothing=123, you're not directly calling the
method -- you're acutally doing an assignment operator, which calls
the
nothing= internally. The assignment operator always returns the
value on
the right side, and the return value from nothing= is ignored.


to go one level deeper on Ken's explanation:
% echo "attr_accessor :x; self.x = 42" | parse_tree_show
s:)block,
s:)call, nil, :attr_accessor, s:)arglist, s:)lit, :x))),
s:)attrasgn, s:)self), :x=, s:)arglist, s:)lit, 42))))

the attrasgn node does the call and returns the value of the arglist
regardless of the call's return value(s).
 
I

Igor Pirnovar

7stud said:
class A
def nothing(data)
return "hello"
end
end

a = A.new
puts a.nothing=(123)

--output:--r1test.rb:51:
undefined method `nothing=' for #<A:0x25364> (NoMethodError)

Sorry, typo "puts o.nothing=(123)" should be "puts o.nothing(123)". It
should be obvious that I screwed up, because i said:
Therefor, this is what I meant:
+-----------------------+
| class MyTest |
| def nothing(data) |
| return false |
| end |
| end |
| o = MyTest.new |
| puts o.nothing(123) |
|-----------------------|
|OUTPUTS: false |
+-----------------------+
 

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
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top