2

I can convert "+" , "-" or "/" to operator use 2.send("-",3)

but it does not work with "+="

a = 2
a += 2 #=> 4

a = 2
a.send("+=", 4) #=> NoMethodError: undefined method `+=' for 2:Fixnum

I have tried to convert symbol first ; but not works too;

how to fix this?

Stefan
  • 109,145
  • 14
  • 143
  • 218
junk
  • 917
  • 3
  • 11
  • 29

1 Answers1

5

2.send("-", 3) works, because - is a method and 2 responds to that method:

2.respond_to?('-') #=> true

= and += on the other hand are not methods:

2.respond_to?('=')  #=> false
2.respond_to?('+=') #=> false

And even if = was a valid method1, then

a = 2
a.send("=", 4)

would be equivalent to:

2.send("=", 4)

or simply:

2 = 4

In other words: it would redefine 2 as 4, something Ruby doesn't allow you to do.

This is because variables (like a above) are not objects. a.send doesn't send a message to the variable a, but to the object, a is referring to (2 in the example).

The same applies to abbreviated assignment like +=:

a = 2
a += 2

is equivalent to:

a = 2
a = a + 2

You can just rewrite it as:

a = 2
a = a.send("+", 2)

The assignment is not part of the method invocation.


1 you can actually define a method = via define_method:

class Foo
  define_method('=') { |other| puts "`=' called with #{other}" }
end

But it is just an ordinary method. In particular, it does not and can not alter the variable the object was assigned-to or the object's identity:

 f = Foo.new
 #=> #<Foo:0x007ff20c0eeda8>
 f.send('=', 123)
 # `=' called with 123
 #=> nil
 f
 #=> #<Foo:0x007ff20c0eeda8>
Stefan
  • 109,145
  • 14
  • 143
  • 218