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

Rubyのsendメソッドを使用するメリットと注意点

Qiita初投稿です。よろしくお願いします。

はじめに

Rubyのsendメソッドを仕事中に使用する機会があり、便利!と思ったものの、慎重に使う必要があることがわかったのでまとめました。

参考文献

現場で使える Ruby on Rails 5速習実践ガイド

sendメソッドとは

レシーバーが持っているメソッドを、文字列(またはシンボル)で指定して呼び出します。
つまり、メソッドを動的に呼び出すことができます。

どんなときに使えるか

以下のように、caseの値によって呼び出すメソッドが異なる場合、caseが増えれば増えるほどコードが膨らんでいき、可読性が下がります。

# 値によって実行するメソッドを分岐させる
class Shape
  def create_shape(shape_type)
    case shape_type
    when "circle" then
      create_shape_circle
    when "square" then
      create_shape_square
    when "triangle" then
      create_shape_triangle
    end
  end

  def create_shape_circle
    ...
  end

  def create_shape_square
    ...
  end

  def create_shape_triangle
    ...
  end
end

shape = Shape.new
shape.create_shape("circle")

上記のコードをsendメソッドを使って書き直すとこうなります。

class Shape
  attr_accessor :shape_type

  def initialize(shape_type)
    @shape_type = shape_type
  end

  def create_shape_circle
    ...
  end

  def create_shape_square
    ...
  end

  def create_shape_triangle
    ...
  end
end

shape = Shape.new("circle")
shape.send("create_shape_#{shape.shape_type}")

メソッドを動的に呼び出せるため、caseでの分岐が不要になりました!
ただし、sendに渡す値によっては、sendを使用せずにメソッドを固定的にコーディングした方が良い場合があります。

sendメソッドに渡してはいけない値

sendメソッドは動的にプログラムの動作を変えられる反面、使い方を誤ると深刻なセキュリティ問題を引き起こす恐れがあります。

特に、ユーザーからの入力をそのままsendに引き渡すと、意図せぬ範囲のデータやプライベートメソッドにまで影響が及ぶ可能性があります。

例)悪意のあるユーザーが「exit」と入力した場合、それがsendに渡されるとアプリケーションが終了してしまう。
※exitはKernelモジュールに定義されているメソッド。KernelモジュールはBasicObject以外のすべてのクラスで使用可能。

そのため、外部から入力された値によって呼び出すメソッドを分岐させる場合は、最初のcase文の例のように、ユーザーの入力を切り分けて個々のメソッドの呼び出しを固定的にコーディングした方が安全です。

まとめ

sendメソッドは動的なメソッド呼び出しができて便利だが、セキュリティ面を考慮し、外部の入力に依存する値は渡さないようにする。

Why do not you register as a user and use Qiita more conveniently?
  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
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