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

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.

On Thu, 26 Feb 2009 09:14:17 -0500, Iñaki Baz C. wrote:

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

Ken B. wrote:

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 :wink:

±----------------------+
| class MyTest |
| def nothing(data) |
| return false |
| end |
| end |
| o = MyTest.new |

puts o.nothing=(123)
OUTPUTS: false

±----------------------+

7stud – wrote:

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ñaki Baz C. wrote:

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

2009/2/26 Igor P. [email protected]:

definition properly would ever see it. The bug showed up in a slightly
 |  o = MyTest.new    |
 |  puts o.nothing=(123) |
 |-----------------------|
 |OUTPUTS: false     |
 ±----------------------+

ok, thanks to all for the explanation.

Igor P. wrote:

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 :wink:

±----------------------+
| 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)

On Feb 26, 2009, at 07:09 , Ken B. wrote:

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).

7stud – wrote:

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:

Take away the equal sign and it will behave like
you’d expect it.

Therefor, this is what I meant:
±----------------------+
| class MyTest |
| def nothing(data) |
| return false |
| end |
| end |
| o = MyTest.new |

puts o.nothing(123)
OUTPUTS: false

±----------------------+

7stud – wrote:

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.