Ich versuche, eine Klasse mit Methoden zu definieren, und eine Klasse, die diese Methoden fehlt, und dann einem Objekt der letzteren Klasse zu erlauben, die Methoden von einer Instanz der früheren Klasse zu "lernen".Wie kopieren wir Singleton-Methoden zwischen verschiedenen Ruby-Klassen?
Dies ist mein Versuch (Ruby 1.9.2) - es bricht (in der Zeile kommentierte "Breaks!"), Wenn ich versuche, den Wert von "Selbst" in der Lambda-Bindung zu ändern.
Wenn Sie herausfinden können, wie Sie das lösen - würde mich das faszinieren.
class Skill
attr_accessor :name
attr_accessor :technique
def initialize(name, &technique_proc)
@name = name
@technique = lambda(&proc)
end
end
class Person
attr_accessor :name
def initialize(name)
@name = name
end
def method_missing(m, *args)
"#{@name} the #{self.class}: I don't know how to #{m}"
end
def learn_skill(skill)
puts "#{@name} the #{self.class} is learning skill: #{skill.name}"
actual_self = self
eval "self = #{actual_self}", skill.technique.binding ####### BREAKS!
define_singleton_method skill.name.to_sym, skill.technique
end
def teach_skill(skill_name)
skill = nil
if self.respond_to?(skill_name)
puts "#{@name} the #{self.class} is teaching skill: #{skill_name}"
skill_method = self.method(skill_name.to_sym)
skill_proc = skill_method.to_proc
skill_lambda = lambda(&skill_proc)
skill = Skill.new(skill_name, &skill_lambda)
end
skill
end
end
class Teacher < Person
def speak(sentence)
"#{@name} the #{self.class} is now saying \"#{sentence}\"!"
end
def jump(number_of_feet)
"#{name} the #{self.class} is now jumping #{number_of_feet} high!"
end
end
miss_mollyflop = Teacher.new("Miss Mollyflop")
little_billey = Person.new("Little Billy")
puts miss_mollyflop.speak("Good morning, children!")
puts little_billey.speak("Good morning, Miss Mollyflop!")
speak_skill = miss_mollyflop.teach_skill("speak")
little_billey.learn_skill(speak_skill)
puts little_billey.speak("Good morning, Miss Mollyflop!")
Der Ausgang dieses ist:
Miss Mollyflop the Teacher is now saying "Good morning, children!"!
Little Billy the Person: I don't know how to speak
Miss Mollyflop the Teacher is teaching skill: speak
Little Billy the Person is learning skill: speak
test.rb:27:in `eval': (eval):1: Can't change the value of self (SyntaxError)
self = #<Person:0x1482270>
^
(eval):1: syntax error, unexpected $end
self = #<Person:0x1482270>
^
from test.rb:27:in `learn_skill'
from test.rb:64:in `<main>'
Konnten Sie sich bemühen, Ihren Code richtig zu formatieren? – Theo
Sie können "self" nicht direkt ändern, es ist schreibgeschützt. –
Ich habe den Code formatiert (kostenlos). Beim nächsten Mal können Sie den Code oder die Ausgabe markieren und dann auf die Schaltfläche "101010" klicken, um sie als Code zu formatieren. –