JohnSmith1976
JohnSmith1976

Reputation: 666

What is the difference between the traditional test = method(arg) and test = send(method, arg)?

I am in the Order model of a Rails application, where I wish to invoke a method for an instance of the Email class.

This first method takes the instance of the Email class (in this example it is called email). It works just fine.

def recursive_search_mails(user, settings)
  emails = user.emails.where(:datetime.gte => self.datetime)

  emails.each do |email|
    notification = email.test_if_notification(user, settings)
    if notification == true
      email.destroy
      return
    end
    correspondance = email.test_if_correspondance(user, settings)
    if correspondance == true
      email.destroy
      return
    end
  end
end

A more concise version of the above code would be this one:

def recursive_search_mails(user, settings)
  emails = user.emails.where(:datetime.gte => self.datetime)

  emails.each do |email|
    %w(notification, correspondance).each do |type|
      is_type = email.send("test_if_#{type}", user, settings)
      if is_type == true
        email.destroy
        return
      end
    end
  end
end

However, it raises this error:

2013-05-09T16:36:11Z 71266 TID-owr7xy0d0 WARN: undefined method `test_if_notification,' for #<Email:0x007fd3a3ecd9b0>

How can this be?

Upvotes: 0

Views: 56

Answers (3)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230286

Other answers deal with the comma, I'll address the difference between approaches.

You invoke methods with send when you don't know method name in advance (at "code-write" time, for the lack of compile-time). Or you do know, but performing "static" calls greatly increases complexity of the code (your case, with duplicated code). In such cases, dynamic invocation (send) is called for.

Upvotes: 4

Dan Tao
Dan Tao

Reputation: 128317

The %w literal prefix creates an array of tokens separated by whitespace.

You have %w(notification, correspondence) which includes the strings "notification," (note the comma) and "correspondence".

Get rid of the comma and you should be good.

Upvotes: 3

user946611
user946611

Reputation:

You have an unwanted comma

Change

%w(notification, correspondance)

to

%w(notification correspondance)

Upvotes: 2

Related Questions