Help us understand the problem. What is going on with this article?

【Ruby on Rails】sendメソッドのいろんな書き方

More than 1 year has passed since last update.

sendメソッドとは

sendとは、レシーバの持っているメソッドを呼び出してくれるメソッドのこと。
今回はrailsも少し絡めて説明していきたいと思います。

引数が一つの書き方【Ruby】

レシーバの持っているメソッドを呼び出し、そのメソッドの戻り値を返します。
以下はメソッドを定義したときの例です。

class User
  def name
    puts "taro"
  end
end

user = User.new
#定義したメソッドを呼び出す
user.name  # => taro

# sendを使った書き方
user.send(:name) # => taro
user.send("name")  # => taro

引数が一つの書き方【Rails】

railsも同様に使えます。
Userインスタンスのnameカラムがあった場合も、同じように書きます。

user = User.new(name: "taro")

user.send(:name) # => taro
user.send("name") # => taro

引数が二つの書き方【Ruby】

第一引数にメソッドを入れ、第二引数に値を入れます。

class User
  def age(num)
    puts "私は#{num}歳です"
  end
end

user = User.new

# 定義したメソッドを呼び出す
user.age(20) # => 私は20歳です

# sendを使った書き方
user.send("age", 20) # => 私は20歳です
user.send(:age, 20) # => 私は20歳です

railsも同様。Userモデルに上と同じageメソッドがあるとします。

user = User.new(age: 20)

user.send(:age, 20) # => 私は20歳です
user.send("name", 20) # => 私は20歳です

カラムに値を入れる【Rails】

sendメソッドで値を入れることもできます。

user = User.new
user.send("age=", 30)

#出力結果
user.age
=> 30

条件別にメソッドを使い分ける【Ruby】

ここまで来て特にメリットを感じたことはないと思いますが、
条件によってメソッドやカラム名を変えて値を入れる場合に使えます。

class User
  attr_accessor :sex
  def initialize(sex = nil)
    @sex = sex
  end

  def man_method
    puts "僕は男です"
  end

  def woman_method
    puts "私は女です"
  end
end

user = User.new
# sexによって使うメソッドを変える
user.sex = "man"
prefix = user.sex == "man" ? "man" : "woman"
user.send("#{prefix}_method") 
# => 僕は男です

user.sex = "woman"
prefix = user.sex == "man" ? "man" : "woman"
user.send("#{prefix}_method")
# => 私は女です

## sendを使った書き方

条件別にカラムに入れる値を変える

例えば、userにageカラムの他に、man_ageカラム, woman_ageカラム があるとします。
(こんなカラムないと思いますが笑)

user = User.new(sex: "man")
sex = user.sex == "man" ? man : woman
user.send("#{sex}_age=", 20) # => man_ageに20が入る

user.sex = "woman"
sex = user.sex == "man" ? man : woman
user.send("#{sex}_age=", 20) # => woman_ageに20が入る

  • sexの値がmanであれば、man_ageカラムに20が入る
  • sexの値がwomanであれば、woman_ageカラムに20が入る

というように条件別に入れるカラムやメソッドを変えたりできます。

メソッド名を文字列として連結

文字列として連結すれば、変数名をメソッド名に組み込んで使えるようにすることもできます。

user = User.new
hoge = "_test"

#上下は同じ
user.send("method" + hoge)
user.method_test

これでuserオブジェクトのmethod_test というメソッドを呼び出すことができます。

まとめ

sendメソッドは、動的にメソッドの挙動を変えたりするときに有効だと思いました。
今回はrubyとrailsに少し分けて説明しましたが、 わかりにくかったらコメントなどいただけると嬉しいです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした