IT박스

Ruby에서 'Monkey Patching'은 정확히 무엇을 의미합니까?

itboxs 2020. 11. 27. 07:55
반응형

Ruby에서 'Monkey Patching'은 정확히 무엇을 의미합니까?


Wikipedia에 따르면 원숭이 패치 는 다음과 같습니다.

원본 소스 코드를 변경하지 않고 동적 언어 [...]의 런타임 코드를 확장하거나 수정하는 방법.

같은 항목의 다음 진술이 나를 혼란스럽게했습니다.

Ruby에서 monkey patch라는 용어는 클래스에 대한 동적 수정을 의미하는 것으로 오해되었으며 종종 런타임에 모든 클래스를 동적으로 수정하는 동의어로 사용됩니다.

Ruby에서 원숭이 패치의 정확한 의미 를 알고 싶습니다 . 다음과 같은 일을하고 있습니까? 아니면 다른 일입니까?

class String
  def foo
    "foo"
  end
end

짧은 대답은 "정확한"의미가 없다는 것입니다. 왜냐하면 그것은 참신한 용어이고 다른 사람들이 그것을 다르게 사용하기 때문입니다. 적어도 위키피디아 기사에서 그 정도를 식별 할 수 있습니다. 일부는 "런타임"코드 (내가 생각하기에 내장 된 클래스)에만 적용한다고 주장하는 반면 일부는이를 사용하여 모든 클래스의 런타임 수정을 참조합니다.

개인적으로 더 포괄적 인 정의를 선호합니다. 결국 내장 클래스 만 수정하는 용어를 사용한다면 다른 모든 클래스의 런타임 수정을 어떻게 언급할까요? 나에게 중요한 것은 소스 코드와 실제 실행중인 클래스간에 차이가 있다는 것입니다.

Ruby에서 monkey patch라는 용어는 클래스에 대한 동적 수정을 의미하는 것으로 오해되었으며 종종 런타임에 모든 클래스를 동적으로 수정하는 동의어로 사용됩니다.

위의 진술은 루비 사용법이 틀렸다고 주장하지만 용어가 진화하고 그것이 항상 나쁜 것은 아닙니다.


내가 몽키 패칭 / 덕 펀칭에 대해 들었던 가장 좋은 설명 RailsConf 2007의 Patrick Ewing입니다.

... 오리처럼 걷다가 오리처럼 말하면 오리 죠? 그래서 만약이 오리가 당신이 원하는 소리를 내지 못한다면, 당신이 기대하는 것을 반환 할 때까지 그 오리를 펀치해야합니다.


몽키 패치는 런타임에 클래스의 메서드 교체 하는 것입니다 ( 다른 사람들이 설명한대로 새 메서드를 추가 하지 않음 ).

코드를 변경하기 위해 매우 명확하지 않고 디버깅하기 어려운 방법 일뿐만 아니라 확장되지도 않습니다. 점점 더 많은 모듈이 원숭이 패치 방법을 시작함에 따라 변경 사항이 서로를 밟을 가능성이 커집니다.


당신이 올바른지; 기존 클래스를 하위 클래스가 아닌 수정하거나 확장 할 때입니다.


이것은 원숭이 패치입니다.

class Float
  def self.times(&block)
    self.to_i.times { |i| yield(i) }
    remainder = self - self.to_i
    yield(remainder) if remainder > 0.0
  end
end

이제 나는 이것이 때때로 유용 할 것이라고 생각하지만 당신이 일상적인 것을 보았다고 상상해보십시오.

def my_method(my_special_number)
  sum = 0
  my_special_number.times { |num| sum << some_val ** num }
  sum
end

그리고 그것은 호출 될 때 가끔 만 끊어집니다 . 주의를 기울이는 사람들에게는 이미 그 이유를 알고 있지만 .times클래스 메서드 가있는 float 유형에 대해 몰랐고 자동으로 my_special_number정수 라고 가정했다고 상상해보십시오 . 매개 변수가 정수, 정수 또는 부동 소수점 일 때마다 제대로 작동합니다 (부동 소수점 나머지가있는 경우를 제외하고 전체 정수가 다시 전달됨). 그러나 소수점 이하 자릿수가있는 숫자를 전달하면 확실히 깨질 것입니다!

gem, Rails 플러그인, 심지어는 프로젝트의 동료가 얼마나 자주 이런 일이 일어날 지 상상해보세요. 이와 같은 작은 방법이 하나 또는 두 개 있으면 찾아서 수정하는 데 시간이 걸릴 수 있습니다.


왜 깨지는 지 궁금하다면 sum정수이고 부동 소수점 나머지가 다시 전달 될 수 있다는 점에 유의하십시오 . 또한 지수 부호는 유형이 동일한 경우에만 작동합니다. 따라서 귀찮은 숫자를 부동 소수점으로 변환했기 때문에 고정되었다고 생각할 수 있습니다. 합계가 부동 소수점 결과를 취할 수 없다는 것을 알기 위해.


파이썬에서 monkeypatching은 당혹감의 표시로 많이 언급됩니다. "나는이 클래스를 몽키 패치해야했는데 ... 실제 클래스에서 원치 않는 동작을 수정하거나 하위 클래스에서 수정하기 위해 로비하는 대신 업스트림 클래스를 잡고 런타임에 수정해야한다고 말하는 데 사용됩니다. 내 경험상 루비 사람들은 몽키 패칭에 대해 그렇게 많이 이야기하지 않는다. 왜냐하면 그것은 특별히 나쁘거나 심지어 주목할만한 것으로 간주되지 않기 때문이다 (따라서 "오리 펀치"). 분명히 다른 종속성에서 사용될 메서드의 반환 값을 변경하는 데주의해야하지만 active_support 및 패싯이 수행하는 방식으로 클래스에 메서드를 추가하는 것은 완벽하게 안전합니다.

10 년 후 업데이트 : 나는 "비교적 안전하다"라고 마지막 문장을 수정합니다. 새로운 메소드로 핵심 라이브러리 클래스를 확장하면 다른 사람이 동일한 아이디어를 얻고 다른 구현 또는 메소드 서명으로 동일한 메소드를 추가하거나 사람들이 핵심 언어 기능을 위해 확장 메소드를 혼동하는 경우 문제가 발생할 수 있습니다. 두 경우 모두 Ruby에서 자주 발생합니다 (특히 active_support 메서드 관련).


일반적으로 낮은 품질의 코드로 자주 Ruby 공개 클래스를 사용하는 임시 변경을 의미합니다.

주제에 대한 좋은 후속 조치 :

http://www.infoq.com/articles/ruby-open-classes-monkeypatching


코드없이 개념 설명 :

정확한 개념에 대한 논의는 필요 이상으로 너무 학술적이고 미묘한 차이가 있습니다. 다음 예제를 통해 간단하게 유지하겠습니다.

자동차의 정상적인 작동

평소에는 어떻게 시동을 걸나요? 간단합니다. 점화 장치를 켜면 차가 시동되고 레이스에 출전합니다!

자동차를 패치하는 원숭이

하지만 다른 사람이 차를 만든 경우에는 어떻게되며 작동 방식을 변경하려면 어떻게해야합니까?

이러한 변경을 위해 자동차 제조 공장에 갈 필요가 없습니다. 보닛 아래로 들어가서 은밀하고 몰래 배선하고 여기 저기에 몇 가지 발병을 추가함으로써 간단히 "원숭이 패치"를 수행 할 수 있습니다. 이 작업을 수행 할 때 무엇을하고 있는지 정말로 알아야합니다. 그렇지 않으면 결과가 상당히 폭발적 일 수 있습니다. 그게 정확히 원하는 것일까 요?

Fabrizzio, 어디 가니?

팔!

월요일, 화요일, 수요일, 목요일, 금요일, 토요일.  이미지는 무료이며 unsplash의 오픈 소스입니다-https://unsplash.com/photos/dyrehVIidQk

"소스 코드를 가까이에 두되 원숭이 패치는 가까이에 두십시오."

참고 URL : https://stackoverflow.com/questions/394144/what-does-monkey-patching-exactly-mean-in-ruby

반응형