Wenn Sie diese Art von Dingen wirklich nur verschönern wollen, warum verpacken Sie nicht alle Ihre Methoden in eine Klasse wie diese:
# 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"
oder, um Ihr Beispiel zu verwenden:
# 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"
Ein weiterer grundlegender Fehler, den Sie gemacht haben, ist die Initialisierung von @a
außerhalb einer Instanzmethode - nur innerhalb der Definition von A
. Das ist ein absolutes No-Go, weil es einfach nicht funktioniert. Denken Sie daran, dass in Ruby alles ein Objekt ist, einschließlich Klassen, und die @
Präfix bedeutet die Instanz Variable des Objekts, das gerade self ist. Innerhalb einer Instanzmethode Definitionen, self
ist eine Instanz der Klasse. Aber außerhalb davon, nur innerhalb der Klassendefinition, self
ist das Klassenobjekt - Sie haben also eine Instanzvariable namens @a
für das Klassenobjekt A
, die keine der Instanzen von A
direkt erreicht werden kann.
Ruby hat einen Grund für dieses Verhalten (Klasseninstanzvariablen können sehr nützlich sein, wenn man weiß, was wenn man weiß, was man tut), aber dies ist eine fortgeschrittene Technik.
Kurz gesagt, initialisieren Sie nur Instanzvariablen in der initialize
Methode.