Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plus equals with ruby send message

Tags:

ruby

I'm getting familiar with ruby send method, but for some reason, I can't do something like this

a = 4
a.send(:+=, 1)

For some reason this doesn't work. Then I tried something like

a.send(:=, a.send(:+, 1))

But this doesn't work too. What is the proper way to fire plus equals through 'send'?

like image 889
orsi Avatar asked Aug 12 '13 09:08

orsi


People also ask

Can you use += in Ruby?

Assignment Operators (==, +=, ||=) These are equivalent to reading the current value & using one of the arithmetic operators with it, then saving the result. You can do this with all the arithmetic operators, including the modulo operator ( % ). But there are two assignment operators that behave in a different way!

What does :: means in Ruby?

The :: is a unary operator that allows: constants, instance methods and class methods defined within a class or module, to be accessed from anywhere outside the class or module. Remember in Ruby, classes and methods may be considered constants too.

What is .send in Ruby?

send is a Ruby method allowing to invoke another method by name passing it any arguments specified. class Klass def hello(*args) "Hello " + args.join(' ') end end k = Klass.new k.send :hello, "gentle", "readers" #=> "Hello gentle readers" Source.

How do you use the send method in Ruby?

Send method basics Typically dot notation is used to a call method on an object. In the code snippet just below, on line 2 the + method is called on the integer object. The send method works similarly to dot notation. The send method invokes the method identified by symbol, passing it any arguments specified.


2 Answers

I think the basic option is only:

a = a.send(:+, 1)

That is because send is for messages to objects. Assignment modifies a variable, not an object.


It is possible to assign direct to variables with some meta-programming, but the code is convoluted, so far the best I can find is:

a = 1
var_name = :a
eval "#{var_name} = #{var_name}.send(:+, 1)"
puts a  # 2

Or using instance variables:

@a = 2
var_name = :@a
instance_variable_set( var_name, instance_variable_get( var_name ).send(:+, 1) )
puts @a  # 3
like image 104
Neil Slater Avatar answered Oct 23 '22 11:10

Neil Slater


See the below :

p 4.respond_to?(:"+=") #  false
p 4.respond_to?(:"=")  #  false
p 4.respond_to?(:"+")  #  true

a+=1 is syntactic sugar of a = a+1. But there is no direct method +=. = is an assignment operator,not the method as well. On the other hand Object#send takes method name as its argument. Thus your code will not work,the way you are looking for.

like image 1
Arup Rakshit Avatar answered Oct 23 '22 11:10

Arup Rakshit