ルビには、特定の変数の値が変更されるたびに呼び出されるフックがありますか?変数が変更されたときに呼び出されるフック
答えて
Ruby用のC拡張を書く場合、誰かが設定するたびにセッターフックを起動するグローバル変数を実際に作ることができます。
しかし、あなたはCを書く必要があり、それを管理するのが苦痛かもしれないので、おそらくそれをしたくないでしょう。
より良い戦略は、変数が適切な方法で読み込まれ、設定されるようにすることです。その後、setterメソッドが呼び出されると、あなたは何でもできます。ここではオブジェクト内の変数をカプセル化する例を次に示します。
class Foo
def bar=(v)
@bar = v
# do some stuff
end
def bar
@bar
end
end
同様に、モジュールまたはクラスの代わりに、オブジェクト内の変数をカプセル化することができます。
+1。あなたが書いたCエクステンションの例を指すことができますか? – Swanand
ええ、https://github.com/ruby/ruby/blob/trunk/README.EXTの 'rb_define_hooked_variable'をチェックしてください。 –
プリアンブル:これは解決策ではありません(pstは既に書いてあります:ありません)が、特殊な状況で役立つ可能性があります。
私の最初の考えは解決策を得るためにfreeze
を使用していた:
module FreezeWarning
def freeze
puts "#{self}: I am changed"
end
end
a = "aa"
a.extend(FreezeWarning)
a.freeze
a << 'b' #aa: I am changed
まず問題:変数の値を変更したときに今、私たちはfreeze
を再定義する必要がありますし、私たちはヒントを得る
a = "aa"
a.freeze
a << 'b' #can't modify frozen string (RuntimeError)
を:There is no way to get the variable name。
あなたは追加の変数(あなたがあなた自身の変数の識別を定義することができ、それは名前であってはなりません)
module FreezeWarning
def change_warning(name)
@varname = name
self.freeze
end
def freeze
puts "<#{@varname}> (#{self}): I am changed"
end
end
a = "aa"
a.extend(FreezeWarning)
a.change_warning('a')
a << 'b' #<a> (aa): I am changed
しかし、より大きな問題でこれを解決する可能性があります、これは、値の変化でのみ動作していません新しい課題:
a = 5
a.freeze
a = 4
p a # -> 4
これは非常に制限された「解決策」です。
アイデアをありがとう。 – sawa
いいえ。ただし、アクセサを使用することはできます。 –