6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Module#refine

Last updated at Posted at 2014-07-25

Module#refine ってなんぞ?

引数 klass で指定したクラスだけに対して、ブロックで指定した機能を提供で きるモジュールを定義します。定義した機能は Module#refine を使用せずに直 接 klass に対して変更を行う場合と異なり、限られた範囲のみ有効にできます。 そのため、既存の機能を局所的に修正したい場合などに用いる事ができます。 
定義した機能は main.using を実行した場合のみ有効になります。

要は?

モンキーパッチを適用する範囲を限定できて便利

モンキーパッチ?

オリジナルのソースコードを変更することなく、実行時に動的言語(例えばSmalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, など)のコードを拡張したり、変更したりする方法である

具体例

文字列を装飾する class

text_decorator.rb
class TextDecorator
  def initialize(str)
    @base_str = str
  end

  def decorate
    gsub_space_to_atmark(surround_quote(@base_str))
  end

  private

  def surround_quote(str)
    "'#{str}'"
  end

  def gsub_space_to_atmark(str)
    str.gsub(' ', "@")
  end
end

puts TextDecorator.new("abc def").decorate #-> "abc@def"

surround_quoteとか、gsub_space_to_atmark は文字列を弄っているだけだから、String を拡張したら、こんなふうにかけるのに....

string.rb
class String
  def surround_quote
    "'#{self}'"
  end

  def gsub_space_to_atmark
    self.gsub(' ', "@")
  end
end

class TextDecorator
  # String を拡張することで、メソッドチェインが実現
  def decorate
    @base_str.surround_quote.gsub_space_to_atmark
  end
end

とは言え、TextDecorator でしか使わないメソッドなのに、 String 全体に影響を与えてしまうのはよろしくない

  • 誰かが別の所で同じメソッドで、String を拡張するかも...?
  • 他の所で思わぬ影響を与えるかも...?

そこで Refinements ですよ

mutable_string.rb

# module MutableString を using している所だけで、下記モンキーパッチが適用される
module MutableString
  refine String do
    def surround_quote
      "'#{self}'"
    end

    def gsub_space_to_atmark
      self.gsub(' ', "@")
    end
  end
end

class TextDecorator
  def initialize(str)
    @base_str = str
  end

  using MutableString

  # String を拡張することで、メソッドチェインが実現
  def decorate
    @base_str.surround_quote.gsub_space_to_atmark
  end
end

# undefined method `gsub_space_to_atmark' for "abc def":String (NoMethodError)
"abc def".gsub_space_to_atmark

これなら安心!!

参考

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?