1

新しい演算子を導入することで、次のことを実現したいと思います(例:=

a := b = {}
b[1] = 2
p a # => {}
p b # => {1=>2}

私が理解している限り、Objectクラスを変更する必要がありますが、必要なものを取得するために何をすべきかわかりません。

require 'superators'
class Object
  superator ":=" operand # update, must be: superator ":=" do |operand|
    # self = Marshal.load(Marshal.dump(operand)) # ???
  end
end

これで私を助けてもらえますか?


アップデート

わかりました、スーパーエーターはおそらくここでは役に立ちませんが、それでもそのようなオペレーターが必要です。モジュールとしてロードできる Ruby の拡張機能を作成するにはどうすればよいですか?

require 'deep_copy_operator'
a !?= b = {} # I would prefer ":=" but don't really care how it is spelled
b[1] = 2
p a # => {}
p b # => {1=>2}
4

2 に答える 2

3

wow, superators look neat! But unfortunately, this won't work for you, for two reasons. First, your operator does not match the regex (you cannot use a colon). Easy enough, find a new operator. But the second one I don't think can be overcome, the superator is basically a method name defined on the object to the left. So you can't use it for assignment statements. If your variable is not defined, then you cannot use it, that would raise an error. And if it is defined, then you can't change its type in any way that is obvious to me (maybe with some level of reflection and metaprogramming that is way beyond anything I know, but it honestly seems unlikely... of course, I would have never expected it to be possible to create superators, so who knows).

So I think you're back to hacking parse.y and rebuilding your Ruby.

于 2010-07-03T10:59:50.930 に答える
2

まず、スーパーエータの構文は次のとおりです。

superator ":=" do |operand|
  #code
end

superator はメタプログラミング マクロであるため、これはブロックです。

第二に、あなたは何かを持っていMarshalます...しかし、それは少し魔法っぽいです. 自分が何をしているのかを正確に理解している限り、自由に使用してください。

self第三に、あなたがしていることは、関数中に変更できないため、superator では実行可能ではありません (私は信じています) 。(他に知っている人がいたら教えてください)

また、あなたの例でaは、メソッドを呼び出す前に、最初に存在して定義する必要があります:=

あなたの最善の策はおそらく次のとおりです。

class Object
  def deep_clone
    Marshal::load(Marshal.dump(self))
  end
end

オブジェクトのディープ クローンを生成します。

a = (b = {}).deep_clone
b[1] = 2
p a # => {}
p b # => {1=>2}
于 2010-07-03T10:28:55.787 に答える