本当にこの種のものをきれいにしたいだけなら、次のようなクラスですべてのメソッドをラップしてみませんか?
# a container to store all your methods you want to use a hash to access
class MethodHash
alias [] send
def one
puts "I'm one"
end
def two
puts "I'm two"
end
end
x = MethodHash.new
x[:one] # prints "I'm one"
x.two # prints "I'm one"
または、例を使用するには:
# a general purpose object that transforms a hash into calls on methods of some given object
class DelegateHash
def initialize(target, method_hash)
@target = target
@method_hash = method_hash.dup
end
def [](k)
@target.send(@method_hash[k])
end
end
class A
def initialize
@a = DelegateHash.new(self, { 0 => :a })
end
def a()
puts "hello world"
end
def b()
@a[0]
end
end
x = A.new
x.a #=> prints "hello world"
x.b #=> prints "hello world"
あなたが犯したもう一つの基本的なエラーは@a
、インスタンスメソッドの外部で初期化したことです-の定義の内部で裸になっていますA
。それはうまくいかないので、これは大したことではありません。ルビーでは、クラスを含むすべてがオブジェクトであり、@
プレフィックスは、現在自己であるオブジェクトのインスタンス変数を意味することを忘れないでください。インスタンスメソッド定義内にself
は、クラスのインスタンスがあります。しかし、その外側、クラス定義のすぐ内側にクラスオブジェクトがあります。そのため、クラスオブジェクトにちなんでself
名付けられたインスタンス変数を定義しました。これは、のどのインスタンスも直接取得できません。@a
A
A
Rubyにはこの振る舞いの理由があります(何をしているのかを知っていれば、クラスインスタンス変数は本当に便利です)が、これはより高度な手法です。
つまり、initialize
メソッドのインスタンス変数のみを初期化します。