• ベストアンサー
  • 困ってます

メソッドのモンキーパッチ

  • 質問No.9227993
  • 閲覧数109
  • ありがとう数1
  • 気になる数0
  • 回答数1
  • コメント数0

お礼率 55% (32/58)

# Ruby 2.1 環境です。

# 変更できないモジュール Mylib があります。
module Mylib
def self.mymethod(n)
puts "hello!" * n
end
def mymethod(*args)
Mylib.mymethod(*args)
end
end

# Mylib は次のように使っています。
#
# 1. クラスメソッドとして呼び出し
#
# Mylib.mymethod 3 # => "hello!hello!hello!"
#
# 2. Mix-in してからメソッド名だけの呼び出し
#
# include Mylib
# mymethod 1 # => "hello!"

# これはちゃんと期待通りの挙動です。

# ----

# 元の Mylib に変更を加えずに、mymethod と同名で
# mymethod の事前処理・# 事後処理を使う側で定義したいです。
#
# 次のコードを書いてみました。
# モジュールを再オープンします。
module Mylib
def self.mymethod_new(n)
# 事前・事後処理を行うメソッドの実装です。
puts "mymethod_new"
Mylib.mymethod_old(n.is_a?(Fixnum) ? n : 1)
end
def mymethod_new(*args)
# alias_method でシンボル参照させるための定義です。
Mylib.mymethod_new(*args)
end
# エイリアスを設定
alias_method :mymethod_old, :mymethod
alias_method :mymethod, :mymethod_new
end

# テスト実行します。
Mylib.mymethod("asdf")
# => "mymethod_new" は印字されず、次の例外が出ます。
# no implicit conversion of String into Integer (TypeError)

# mymethod_new を通っていないようです。
# どのように記述すれば良いでしょうか?

質問者が選んだベストアンサー

  • 回答No.1
  • ベストアンサー

ベストアンサー率 48% (80/166)

ruby のクラスメソッドにaliasを張る場合は、class<< selfを使って囲うことで実現できます。
これを使うと良いでしょう。

------------------------------------------------------------------------------------------

# 古いMylibの実装
module Mylib
def self.mymethod(n)
puts "hello!" * n
end

def mymethod(*args)
Mylib.mymethod(*args)
end
end


module Mylib
def self.mymethod_new(n)
# 事前・事後処理を行うメソッドの実装です。
puts "mymethod_new"
Mylib.mymethod_old(n.is_a?(Fixnum) ? n : 1)
end

def mymethod_new(*args)
# alias_method でシンボル参照させるための定義です。
Mylib.mymethod_new(*args)
end

# クラスメソッドにエイリアスを設定する場合は、class<< selfで囲う
class<< self
alias_method :mymethod_old, :mymethod
alias_method :mymethod, :mymethod_new
end
end

p Mylib.mymethod_new(3)
------------------------------------------------------------------------------------------
お礼コメント
sumire_kanou

お礼率 55% (32/58)

ありがとうございました。期待どおりに書くことができました。class<< self がミソなのですね!勉強になりました。
投稿日時:2016/09/13 21:52
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ