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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0f1f17ba297242e9d3c86d4cc0a6ea85?d=identicon&s=25 Iñaki Baz Castillo (Guest)
on 2009-02-26 15:21
(Received via mailing list)
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.
851acbab08553d1f7aa3eecad17f6aa9?d=identicon&s=25 Ken Bloom (Guest)
on 2009-02-26 16:10
(Received via mailing list)
On Thu, 26 Feb 2009 09:14:17 -0500, Iñaki Baz Castillo 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
46a8ebdfabc2485407f89a2db5bdafb7?d=identicon&s=25 Igor Pirnovar (rooby)
on 2009-02-26 16:30
Ken Bloom 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 ;)

  +-----------------------+
  |  class MyTest         |
  |    def nothing(data)  |
  |      return false     |
  |    end                |
  |  end                  |
  |  o = MyTest.new       |
  |  puts o.nothing=(123) |
  |-----------------------|
  |OUTPUTS: false         |
  +-----------------------+
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-26 16:52
Iñaki Baz Castillo 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
46a8ebdfabc2485407f89a2db5bdafb7?d=identicon&s=25 Igor Pirnovar (rooby)
on 2009-02-26 16:57
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.
0f1f17ba297242e9d3c86d4cc0a6ea85?d=identicon&s=25 Iñaki Baz Castillo (Guest)
on 2009-02-26 17:50
(Received via mailing list)
2009/2/26 Igor Pirnovar <gooigpi@gmail.com>:
> 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.
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-26 19:52
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.
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-26 20:26
Igor Pirnovar 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 ;)
>
>   +-----------------------+
>   |  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)
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2009-02-26 20:36
(Received via mailing list)
On Feb 26, 2009, at 07:09 , Ken Bloom 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).
46a8ebdfabc2485407f89a2db5bdafb7?d=identicon&s=25 Igor Pirnovar (rooby)
on 2009-02-26 22:39
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         |
  +-----------------------+
This topic is locked and can not be replied to.