최근에 Ruby 클래스에서 load
을 두 번 호출하면 버그가 발생하는 문제가 발생했습니다 (여기에 real-world example). 이는 클래스 본문에서 stateful 메서드 호출이 발생하고 load
이이 메서드를 두 번 실행하게했기 때문입니다. 간단한 예는 다음과 같다 :Ruby 클래스 정의에서 클래스 수준 메소드 호출이 멱등수입니까?
base.rb
:
class Base
def foo
puts "BASE"
end
end
derived.rb
하십시오 REPL에서
require "./base"
class Derived < Base
alias_method :foo_aliased, :foo
def foo
puts "DERIVED!"
end
end
실행이 예에서는
$ load './derived.rb'
> true
$ Derived.new.foo
> DERIVED!
> nil
$ Derived.new.foo_aliased
> BASE
> nil
$ load './derived.rb'
> true
$ Derived.new.foo
> DERIVED!
> nil
$ Derived.new.foo_aliased
> DERIVED!
> nil
, 제 load
원인 alias_method
을 원래 앨리어스를 깨뜨리는 것. . 결과적으로 원본 메소드에 별명이없는 코드를 사용하지 못했습니다.
무차별 클래스 다시로드는 크게 load
의 사용을 금지하는 것이 쉬운 일이 아닙니다 것을 (예를 들어, 당신은 그것을 Spork를 사용 RSpec에 구성에 대한 each_run
절에 많은 참조) 충분히 일반적입니다. 따라서 버그를 방지하는 유일한 방법은 클래스 정의가 "멱등수"가되도록하는 것입니다. 즉, 클래스 정의에서 호출하려는 메소드가 호출 횟수에 관계없이 동일한 결과를 생성해야합니다. 재로드가 더 많은 코드를 깨뜨리지 않는다는 사실은 무언의 관행을 제안하는 것처럼 보입니다.
루비 클래스 디자인을위한 스타일 가이드가 있습니까? 그렇다면 이러한 의미를 적용하는 일반적인 기술은 무엇입니까? 일부 메소드의 경우 동일한 메소드로 동일한 메소드를 재실행하지 못하도록 일부 메모를 수행 할 수 있지만 alias_method
과 같은 다른 것들은 해결하기가 더 어려워 보입니다.
충분합니다. 파일이 모듈/클래스 만 정의한다는 추가 가정을 통해 클래스가 여러 번로드 될 때 다르게 동작 할 수있는 일반적인 경우를 알고 있습니까? –
예를 들어 임의의 숫자를 사용하여 상수를 정의하고이를 시드로 사용하여 일부 문자열을 인코딩한다고 가정합니다. 로드 할 때마다 다르게 인코딩되며, 마지막로드에서 가져온 시드를 사용하여 디코딩하려고하면 이전에 인코딩 된 시드와 관련된 문제가 발생합니다. – sawa
또한 충분하지만 공정한 요구 사항을 확장하면 클래스 정의 (메서드 호출 및 할당 포함)에 모든 상태 저장 표현식이 포함되므로 다시로드하는 것이 안전하다는 의미입니까? –