どのオブジェクトがメソッドと呼ばれるかを決定する方法はありますか?
-
01-10-2019 - |
質問
Rubyのメッセージパスインフラストラクチャは、これに巧妙なトリックがあるかもしれないことを意味することを願っています。
呼び出しオブジェクトを決定するにはどうすればよいですか?現在のメソッドと呼ばれるオブジェクトは?
解決
オプションとして、aがあります binding_of_caller
宝石 これにより、コールスタック(発信者、発信者の発信者など)のいずれかの発信者のコンテキストでコードを実行できます。検査に役立ちます(読む コールスタックの任意の位置で何かをします)使用されているように、開発中のスタックを呼び出します better_errors
.
クラスのオブジェクト
Binding
コード内の特定の場所で実行コンテキストをカプセル化し、将来の使用のためにこのコンテキストを保持します。
言及する必要があります、 この手法は、デバッグ、楽しみ、教育目的にのみ使用する必要があります, 、それはOOPの原則に本当にひどく違反しているからです。
主にのためです eval
.
物を準備しましょう:
require 'binding_of_caller' # I assume, you installed this gem already?
取得します すぐに (スタックで最も近いので、したがって 0
)発信者インスタンス:
binding.of_caller(0).eval('self')
...または即時の呼び出し方法:
binding.of_caller(0).eval('__method__')
コールスタックを上げる必要がある場合は、以外の数値を使用してください 0
発信者のバインディングを取得するため。
ひどくハッキー。しかし、あなたが本当にこれを必要とするなら - あなたはそこに行きます。
他のヒント
関心のある関数を通ってコードの行を簡単に見ることができます
caller.first
関連する関数と呼ばれるファイル名と行番号を教えてくれます。その後、どのオブジェクトがどのオブジェクトであるかを戻すことができます。
ただし、おそらくインスタンスメソッド内で、特定の関数と呼ばれるオブジェクトの後に、あなたはもっとそうです。私はこれを理解する方法を知っていませんが、カプセル化にひどく違反しているように見えるので、とにかく使用しません。
最高のテクノロジー:
1 # phone.rb
2 class Phone
3 def caller_id
4 caller
5 end
6 end
7
8 class RecklessDriver
9 def initialize
10 @phone = Phone.new
11 end
12 def dial
13 @phone.caller_id
14 end
15 end
16
17 p = Phone.new
18 p.caller_id.inspect # => ["phone.rb:18:in `<main>'"]
19
20 macek = RecklessDriver.new
22 macek.dial.inspect # => ["phone.rb:13:in `dial'", "phone.rb:22:in `<main>'"]
ノート: 実証目的のためのライン番号。 phone.rb:X
ラインを指します X
スクリプトの。
見る phone.rb:13
!これ dial
メソッドは電話を送信したものです!と phone.rb:22
使用した無謀なドライバーを指します dial
方法!
あなたは好きです self
?
irb> class Object
.. def test
.. self
.. end
.. end
=> nil
irb> o = Object.new
=> #<Object:0xb76c5b6c>
irb> o.test
=> #<Object:0xb76c5b6c>
ピーターズ 答え 生産コードの例で使用されます
私の会社では、私たちは非難していました deleted
の味の旗 パラノイアジェム deleted_at
桁。コードベローは、列を削除する前にすべてがうまくいくことを保証していた方法です(このコードを展開し、2〜3日間のライブの後、移行を展開する remoove_column :lessons, :deleted
class Lesson < ActiveRecord::Base
def deleted
if caller.select { |c| c.match /serialization\.rb/ }.any?
# this is Rails object mapping
!!deleted_at
else
raise 'deplicated - deleted was replaced by deleted_at'
end
end
end