메소드가있는 클래스와 그 메소드가없는 클래스를 정의하려고 시도하고 있으며, 후자의 클래스의 객체가 이전 클래스의 인스턴스에서 메소드를 '학습'할 수있게하려고합니다.서로 다른 Ruby 클래스간에 싱글 톤 메소드를 복사하는 방법은 무엇입니까?
내 시도 (Ruby 1.9.2) - 람다 바인딩에서 'self'의 값을 변경하려고 시도 할 때 (줄 바꿈으로 "BREAKS!") 중단됩니다.
당신이 이것을 해결하는 방법을 찾을 수 있다면 - 나는 알아 내서 매료 될 것입니다.
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!")
이의 출력은 다음과 같습니다
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>'
코드를 올바르게 포맷 할 수 있습니까? – Theo
'self'는 직접 변경할 수 없으며 읽기 전용입니다. –
코드 포맷이 고정되어 있습니다 (무료). 다음 번에는 코드 또는 출력을 강조 표시 한 다음 "101010"버튼을 클릭하여 코드 형식을 지정할 수 있습니다. –