Ruby에서“foo = ()”메소드가 정의되어 있는지 어떻게 확인하나요?


81

Ruby에서는 foo = (bar) 메소드를 정의 할 수 있습니다.

irb(main):001:0> def foo=(bar)
irb(main):002:1>   p "foo=#{bar}"
irb(main):003:1> end
=> nil

이제 정의되었는지 확인하고 싶습니다.

irb(main):004:0> defined?(foo=)
SyntaxError: compile error
(irb):4: syntax error, unexpected ')'
 from (irb):4
 from :0

여기에서 사용할 적절한 구문은 무엇입니까? "foo ="를 이스케이프 처리하여 정의 된 파일로 올바르게 전달되도록하는 방법이 있어야한다고 생각합니다. 운영자.

답변:


132

문제는 foo=방법이 할당에 사용되도록 설계 되었다는 것 입니다. defined?다음과 같은 방법으로 진행 상황을 확인할 수 있습니다 .

defined? self.foo=()
#=> nil
defined? self.foo = "bar"
#=> nil

def foo=(bar)
end

defined? self.foo=()
#=> "assignment"
defined? self.foo = "bar"
#=> "assignment"

다음과 비교하십시오.

def foo
end

defined? foo
#=> "method"

foo=메서드가 정의 되었는지 테스트하려면 respond_to?대신 다음을 사용해야 합니다.

respond_to? :foo=
#=> false

def foo=(bar)
end

respond_to? :foo=
#=> true

감사! 이것은 내 문제를 해결합니다. foo =를 이스케이프 처리 할 수있는 방법이 있는지 여전히 궁금합니다. 하지만 적어도 지금은 넘어갈 수 있습니다.
Alex Boisvert

1
여기서 문제 foo=는 항상 할당에 사용되므로 "assignment"테스트하면 Ruby가 반환 됩니다 defined? foo()(업데이트 된 답변 참조).
molf

43

메소드를 사용하여 메소드가 존재하는지 확인할 수 있으며 respond_to?, 예 bar.respond_to?(:foo=)를 들어 객체 bar에 메소드가 있는지 확인 하기 위해 기호를 전달할 수 foo=있습니다. 클래스의 인스턴스가 메서드에 응답하는지 알고 싶다면 method_defined?클래스 (또는 모듈)에서 사용할 수 있습니다 (예 : Foo.method_defined?(:bar=).

defined?메소드는 아니지만 피연산자의 설명을 반환하는 연산자입니다 (또는 정의되지 않은 경우 nil이므로 if 문에서 사용할 수 있음). 피연산자는 상수, 변수, 할당, 메서드, 메서드 호출 등과 같은 모든 표현식이 될 수 있습니다. 이렇게 할 때 작동하지 않는 이유 defined?(foo=)는 괄호 때문에 건너 뛰고 더 많이 작동해야하기 때문입니다. 예상대로 이하입니다. 즉 defined?, 매우 이상한 연산자이며 아무도 그것을 사용하여 메서드의 존재를 테스트하지 않습니다.


respond_to ?, responds_to가 아닙니까?
0x4a6f4672

3
아, 루비 코어 라이브러리의 맞춤법 ... respond_to?, start_with?, end_with?.
Theo

3
stackoverflow.com/questions/5280556/… TL; DR이라는 이름 뒤에있는 선택에 대한 멋진 설명이 있습니다you.knock if you.respond_to?(:knock)
drewish
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.