class String
def hello
"world"
end
end
String.class_eval {
def world
"hello"
end
}
"a".world
=> "hello"
"b".hello
=> "world"
그들은 기존의 클래스에 메소드를 추가하는 것과 같은 일을하는 것처럼 보입니다. 차이점은 무엇입니까?원숭이 패치 대 class_eval?
class String
def hello
"world"
end
end
String.class_eval {
def world
"hello"
end
}
"a".world
=> "hello"
"b".hello
=> "world"
그들은 기존의 클래스에 메소드를 추가하는 것과 같은 일을하는 것처럼 보입니다. 차이점은 무엇입니까?원숭이 패치 대 class_eval?
class_eval
하면 더욱 동적 인 일을 할 수 있습니다
>> met = "hello" #=> "hello"
>> String.class_eval "def #{met} ; 'hello' ; end" #=> nil
>> "foo".hello #=> "hello"
개념적 클래스 재개 (또는 원숭이 패치를) 할 class_eval. 구문상의 차이가 대부분 있습니다. 문자열을 class_eval
으로 전달하면 (Michael의 예와 같이) 대부분 class String; ... end
과 같은 문자열 내부 구문을 사용합니다. 당신이 블록 전달하는 경우 : String.class_eval { ... }
를 다음과 같이는 비교 :
는 다른 차이점을 알고 재미있을 것 CAN
다른 답변은 좋습니다. 추가 하시려는 경우 class_eval
은 참조 클래스가 상수가 아니거나 특정 객체를 패치 할 때 사용할 수 있습니다.
huh = String
class huh
end
SyntaxError: (eval):2: class/module name must be CONSTANT
huh.class_eval <<-eof
def mamma
puts :papa
end
eof
"asdff".mamma
=> papa
당신은 affectin 전체 루트 클래스없이 특정 개체를 패치 class_eval
를 사용할 수 있습니다.
class << obj
...
end
instance_eval
일부 사용에 의해 약간 다른 동작을해야합니다 :로
obj = "asd"
obj.singleton_class.class_eval <<-eof
def asd
puts "gah"
end
undef_method :some_method
위
은 동일합니다. How to monkey patch a ruby class inside a method 는 또한 instance_eval
대 class_eval
에 대한 질문이 있었다하지만 링크가 유용하지 않습니다
나는 흥미있는이 질문에 대한 답을 찾을 수 있습니다.