복붙노트

[RUBY-ON-RAILS] 루비의 액세스 방법을 인수하는 방법은 무엇입니까?

RUBY-ON-RAILS

루비의 액세스 방법을 인수하는 방법은 무엇입니까?

내가 구글하는 방법을 생각하지 않은 이후 루비와 ROR 그것에게 매일 사랑에 새로운, 그래서 여기에 (내가 시도 :)) 내 질문입니다

우리는 방법을

def foo(first_name, last_name, age, sex, is_plumber)
    # some code
    # error happens here
    logger.error "Method has failed, here are all method arguments #{SOMETHING}"    
end

그래서 하나 하나 나열하지 않고, 메소드에 전달 된 모든 인수를 얻을 수있는 방법을 찾고있는 무슨. 이 루비 때문에 나는 방법이 가정 :)는 자바 있었다면 난 그냥 그들을 나열합니다 :)

출력은 다음과 같습니다

Method has failed, here are all method arguments {"Mario", "Super", 40, true, true}

해결법

  1. ==============================

    1.루비 1.9.2 이상에서 해당 메서드에 대한 매개 변수의 목록을 얻을 수있는 방법에 매개 변수 방법을 사용할 수 있습니다. 이 매개 변수의 이름을 나타내는 쌍의 목록을 반환하고 그것이 필요한지 여부.

    루비 1.9.2 이상에서 해당 메서드에 대한 매개 변수의 목록을 얻을 수있는 방법에 매개 변수 방법을 사용할 수 있습니다. 이 매개 변수의 이름을 나타내는 쌍의 목록을 반환하고 그것이 필요한지 여부.

    EG

    당신이 할 경우

    def foo(x, y)
    end
    

    그때

    method(:foo).parameters # => [[:req, :x], [:req, :y]]
    

    당신은 현재 메소드의 이름을 얻기 위해 특별한 변수 __METHOD__를 사용할 수 있습니다. 그래서 방법 내에서 매개 변수의 이름을 통해 얻을 수 있습니다

    args = method(__method__).parameters.map { |arg| arg[1].to_s }
    

    그런 다음 이름과 각 매개 변수의 값을 표시 할 수 있습니다

    logger.error "Method failed with " + args.map { |arg| "#{arg} = #{eval arg}" }.join(', ')
    

    참고 :이 답변은 원래 작성된 이후, 루비 평가의 현재 버전에서 더 이상 기호로 호출 할 수 있습니다. 매개 변수 이름의 목록을 구축 할 때이 문제를 해결하기 위해 명시 적 그리고 to_s가 추가되었습니다 즉 parameters.map {| 인수 | ARG [1]} .to_s

  2. ==============================

    2.루비 2.1 이후는 메서드 매개 변수 (인수)을 포함한 모든 지역 변수의 값을 읽을 binding.local_variable_get 사용할 수 있습니다. 당신이 피하기 악마의 평가에 허용 대답을 향상시킬 수 있음에 감사합니다.

    루비 2.1 이후는 메서드 매개 변수 (인수)을 포함한 모든 지역 변수의 값을 읽을 binding.local_variable_get 사용할 수 있습니다. 당신이 피하기 악마의 평가에 허용 대답을 향상시킬 수 있음에 감사합니다.

    def foo(x, y)
      method(__method__).parameters.map do |_, name|
        binding.local_variable_get(name)
      end
    end
    
    foo(1, 2)  # => 1, 2
    
  3. ==============================

    3.이 처리하는 한 가지 방법은 다음과 같습니다

    이 처리하는 한 가지 방법은 다음과 같습니다

    def foo(*args)
        first_name, last_name, age, sex, is_plumber = *args
        # some code
        # error happens here
        logger.error "Method has failed, here are all method arguments #{args.inspect}"    
    end
    
  4. ==============================

    4.이 흥미로운 질문이다. 어쩌면 local_variables를 사용하고 계십니까? 그러나 평가를 사용하는 것보다 다른 방법이 있어야합니다. 나는 커널 문서에서 찾고 있어요

    이 흥미로운 질문이다. 어쩌면 local_variables를 사용하고 계십니까? 그러나 평가를 사용하는 것보다 다른 방법이 있어야합니다. 나는 커널 문서에서 찾고 있어요

    class Test
      def method(first, last)
        local_variables.each do |var|
          puts eval var.to_s
        end
      end
    end
    
    Test.new().method("aaa", 1) # outputs "aaa", 1
    
  5. ==============================

    5.

      def foo(x, y)
        args(binding)
      end
    
      def args(callers_binding)
        callers_name = caller[0][/`.*'/][1..-2]
        parameters = method(callers_name).parameters
        parameters.map { |_, arg_name|
          callers_binding.local_variable_get(arg_name)
        }    
      end
    
  6. ==============================

    6.당신은 상수를 같은 정의 할 수 있습니다 :

    당신은 상수를 같은 정의 할 수 있습니다 :

    ARGS_TO_HASH = "method(__method__).parameters.map { |arg| arg[1].to_s }.map { |arg| { arg.to_sym => eval(arg) } }.reduce Hash.new, :merge"
    

    그리고 같은 코드에서 사용 :

    args = eval(ARGS_TO_HASH)
    another_method_that_takes_the_same_arguments(**args)
    
  7. ==============================

    7.내가 더 가기 전에, 당신은 foo는에 너무 많은 인수를 전달하고 있습니다. 그 모든 인수가 모델의 특성이 올바른 것 같습니다? 당신은 정말 객체 자체를 전달해야합니다. 연설의 끝.

    내가 더 가기 전에, 당신은 foo는에 너무 많은 인수를 전달하고 있습니다. 그 모든 인수가 모델의 특성이 올바른 것 같습니다? 당신은 정말 객체 자체를 전달해야합니다. 연설의 끝.

    당신은 "플랫"인수를 사용할 수 있습니다. 그것은 배열로 모든 것을 밀 친다. 그것은과 같을 것이다 :

    def foo(*bar)
      ...
      log.error "Error with arguments #{bar.joins(', ')}"
    end
    
  8. ==============================

    8.당신이 메서드 서명을 변경한다면, 당신은 이런 식으로 뭔가를 할 수 있습니다 :

    당신이 메서드 서명을 변경한다면, 당신은 이런 식으로 뭔가를 할 수 있습니다 :

    def foo(*args)
      # some code
      # error happens here
      logger.error "Method has failed, here are all method arguments #{args}"    
    end
    

    또는:

    def foo(opts={})
      # some code
      # error happens here
      logger.error "Method has failed, here are all method arguments #{opts.values}"    
    end
    

    이 경우, 보간 인수 또는 opts.values ​​배열 될 것입니다,하지만 당신은 쉼표에 경우에 가입 할 수 있습니다. 건배

  9. ==============================

    9.그것은이 질문에 그냥 발표 한 보석 I, https://github.com/ericbeland/exception_details 함께 할 수 달성하려고하는 것처럼 보인다. 그것은 구출 예외에서 지역 변수와 vlaues (그리고 인스턴스 변수)를 나열합니다. 가치가보고 될 수 ...

    그것은이 질문에 그냥 발표 한 보석 I, https://github.com/ericbeland/exception_details 함께 할 수 달성하려고하는 것처럼 보인다. 그것은 구출 예외에서 지역 변수와 vlaues (그리고 인스턴스 변수)를 나열합니다. 가치가보고 될 수 ...

  10. ==============================

    10.당신은 해시로 인수를해야하고, 당신이 매개 변수의 까다로운 추출과을 오염 방식의 몸에 원하지 않는 경우, 이것을 사용 :

    당신은 해시로 인수를해야하고, 당신이 매개 변수의 까다로운 추출과을 오염 방식의 몸에 원하지 않는 경우, 이것을 사용 :

    def mymethod(firstarg, kw_arg1:, kw_arg2: :default)
      args = MethodArguments.(binding) # All arguments are in `args` hash now
      ...
    end
    

    그냥 프로젝트에이 클래스를 추가 :

    class MethodArguments
      def self.call(ext_binding)
        raise ArgumentError, "Binding expected, #{ext_binding.class.name} given" unless ext_binding.is_a?(Binding)
        method_name = ext_binding.eval("__method__")
        ext_binding.receiver.method(method_name).parameters.map do |_, name|
          [name, ext_binding.local_variable_get(name)]
        end.to_h
      end
    end
    
  11. ==============================

    11.함수가 어떤 클래스 내에있을 경우, 당신은 이런 식으로 뭔가를 할 수 있습니다 :

    함수가 어떤 클래스 내에있을 경우, 당신은 이런 식으로 뭔가를 할 수 있습니다 :

    class Car
      def drive(speed)
      end
    end
    
    car = Car.new
    method = car.method(:drive)
    
    p method.parameters #=> [[:req, :speed]] 
    
  12. from https://stackoverflow.com/questions/9211813/is-there-a-way-to-access-method-arguments-in-ruby by cc-by-sa and MIT license