Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

'메소드' 방식의 재미

블록만 사용하는 함수에 메서드를 전달하고 싶었던 적이 있습니까? 또는 개체의 슈퍼클래스 중 호출하려는 메서드가 손상되었는지 알아내셨습니까?

method를 사용하면 이러한 작업을 쉽게 수행할 수 있습니다. 방법. 잘 사용하면 종속성에 대해 배우고 디버깅 시간을 절약하고 필요한 위치에 코드를 가져올 수 있습니다.

람다만큼 쉬운 방법

많은 Ruby 메서드는 블록이나 람다를 사용합니다. 그러나 람다에서와 같이 메서드를 다른 메서드에 직접 전달할 수는 없습니다. method를 사용해야 합니다. 첫 번째:

irb(main):001:0> sin_method = Math.method(:sin)
=> #<Method: Math.sin>
irb(main):002:0> (1..10).map(&sin_method)
=> [0.8414709848078965, 0.9092974268256817, 0.1411200080598672, -0.7568024953079282, -0.9589242746631385, -0.27941549819892586, 0.6569865987187891, 0.9893582466233818, 0.4121184852417566, -0.5440211108893699]

여기에서 무슨 일이 일어나고 있습니까?

첫 번째 줄은 Math.sin 메서드를 변경합니다. method로 물체. 람다와 마찬가지로 `Method` 객체는 `call`에 응답합니다. method 개체는 to_proc에 응답합니다. (고마워, 베누아). 따라서 람다를 사용하는 동일한 위치에서 사용할 수 있습니다.

irb(main):004:0> sin_method = -> (x) { Math.sin(x) }
=> #<Proc:0x007fe9f90a9bd8@(irb):4 (lambda)>
irb(main):005:0> (1..10).map(&sin_method)
=> [0.8414709848078965, 0.9092974268256817, 0.1411200080598672, -0.7568024953079282, -0.9589242746631385, -0.27941549819892586, 0.6569865987187891, 0.9893582466233818, 0.4121184852417566, -0.5440211108893699]

첫 번째 줄을 다시 살펴보십시오. 람다를 사용하는 이 코드는 method를 사용하여 이전 코드와 동일한 방식으로 작동합니다. .

코드 작성 방법에 따라 method 파악 객체는 람다로 래핑하는 것보다 훨씬 쉬울 수 있습니다. 따라서 람다가 필요하고 메서드만 있으면 method를 기억하세요. 방법.

그 방법은 어디에서 왔습니까?

방금 개체에서 메서드를 호출했는데 예상하지 못한 작업을 수행합니다. 누군가 덮어썼거나 원숭이 패치를 한 것일 수 있습니다. 이것을 어떻게 알아내나요?

당신은 할 수 있습니다 몇 시간 동안 소스 코드를 파헤칩니다. 하지만 method 속도를 높일 수 있는 두 가지 방법이 있습니다.

어떤 클래스가 호출하는 메서드를 정의했는지 확인하려면 owner를 사용하세요. :

irb(main):003:0> Task.new.method(:valid?).owner
=> ActiveRecord::Validations

좀 더 깊이 들어가 정확히 어디인지 파악하고 싶을 때 메서드가 정의되었습니다. source_location을 사용하세요. :

irb(main):004:0> Task.new.method(:valid?).source_location
=> ["/usr/local/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta2/lib/active_record/validations.rb", 55]

source_location 배열을 반환합니다. 첫 번째 요소는 메서드가 정의된 파일의 경로이고 두 번째 요소는 줄 번호입니다. 이것들을 사용하면 다음에 볼 위치를 정확히 알 수 있습니다.

소스 읽기(파기할 필요 없이)

어디 메소드가 정의된 경우 어떻게 정의되어 있습니다.

method 스스로 할 수 없습니다. 하지만 method_source를 설치하면 gem을 사용하면 콘솔에서 바로 여러 메서드의 소스 코드를 볼 수 있습니다.

irb(main):002:0> puts Task.new.method(:valid?).source
    def valid?(context = nil)
      context ||= (new_record? ? :create : :update)
      output = super(context)
      errors.empty? && output
    end
=> nil

댓글도 볼 수 있습니다.

irb(main):003:0> puts Task.new.method(:valid?).comment
# Runs all the validations within the specified context. Returns +true+ if
# no errors are found, +false+ otherwise.
#
# Aliased as validate.
#
# If the argument is +false+ (default is +nil+), the context is set to <tt>:create</tt> if
# <tt>new_record?</tt> is +true+, and to <tt>:update</tt> if it is not.
#
# Validations with no <tt>:on</tt> option will run no matter the context. Validations with
# some <tt>:on</tt> option will only run in the specified context.
=> nil

꽤 멋지죠? 문서가 콘솔에 있습니다!

자기 성찰은 대단합니다

내가 가장 좋아하는 Ruby 클래스는 코드 내에서 코드를 검사할 수 있는 클래스입니다. Class와 같은 클래스 , Modulemethod . 이것들을 사용하면 실행되는 코드에 대해 많은 것을 배우고 즉시 수정할 수 있습니다. 이 수업을 잘 배우고 API를 공부하면 Ruby로 놀라운 일을 할 수 있습니다.