development

define_method에 인수를 어떻게 전달합니까?

big-blog 2020. 6. 10. 07:52
반응형

define_method에 인수를 어떻게 전달합니까?


define_method를 사용하여 정의되는 메소드에 인수를 전달하고 싶습니다. 어떻게해야합니까?


define_method에 전달하는 블록은 일부 매개 변수를 포함 할 수 있습니다. 정의 된 메소드가 인수를 허용하는 방식입니다. 메소드를 정의 할 때 실제로 블록의 별칭을 지정하고 클래스에서 참조를 유지합니다. 매개 변수는 블록과 함께 제공됩니다. 그래서:

define_method(:say_hi) { |other| puts "Hi, " + other }

... 및 선택적 매개 변수를 원하는 경우

 class Bar
   define_method(:foo) do |arg=nil|                  
     arg                                                                                          
   end   
 end

 a = Bar.new
 a.foo
 #=> nil
 a.foo 1
 # => 1

... 당신이 원하는만큼의 주장

 class Bar
   define_method(:foo) do |*arg|                  
     arg                                                                                          
   end   
 end

 a = Bar.new
 a.foo
 #=> []
 a.foo 1
 # => [1]
 a.foo 1, 2 , 'AAA'
 # => [1, 2, 'AAA']

...의 조합

 class Bar
   define_method(:foo) do |bubla,*arg|
     p bubla                  
     p arg                                                                                          
   end   
 end

 a = Bar.new
 a.foo
 #=> wrong number of arguments (0 for 1)
 a.foo 1
 # 1
 # []

 a.foo 1, 2 ,3 ,4
 # 1
 # [2,3,4]

... 모두

 class Bar
   define_method(:foo) do |variable1, variable2,*arg, &block|  
     p  variable1     
     p  variable2
     p  arg
     p  block.inspect                                                                              
   end   
 end
 a = Bar.new      
 a.foo :one, 'two', :three, 4, 5 do
   'six'
 end

최신 정보

루비 2.0 더블 플랫 소개 **((별 2 개) I 견적이 ) 수행을 :

Ruby 2.0은 키워드 인수를 도입했으며 **는 *와 같은 역할을하지만 키워드 인수에는 적용됩니다. 키 / 값 쌍이있는 해시를 반환합니다.

... 물론 정의 메소드에서도 사용할 수 있습니다 :)

 class Bar 
   define_method(:foo) do |variable1, variable2,*arg,**options, &block|
     p  variable1
     p  variable2
     p  arg
     p  options
     p  block.inspect
   end 
 end 
 a = Bar.new
 a.foo :one, 'two', :three, 4, 5, ruby: 'is awesome', foo: :bar do
   'six'
 end
# :one
# "two"
# [:three, 4, 5]
# {:ruby=>"is awesome", :foo=>:bar}

명명 된 속성 예 :

 class Bar
   define_method(:foo) do |variable1, color: 'blue', **other_options, &block|
     p  variable1
     p  color
     p  other_options
     p  block.inspect
   end
 end
 a = Bar.new
 a.foo :one, color: 'red', ruby: 'is awesome', foo: :bar do
   'six'
 end
# :one
# "red"
# {:ruby=>"is awesome", :foo=>:bar}

I was trying to create example with keyword argument, splat and double splat all in one:

 define_method(:foo) do |variable1, variable2,*arg, i_will_not: 'work', **options, &block|
    # ...

or

 define_method(:foo) do |variable1, variable2, i_will_not: 'work', *arg, **options, &block|
    # ...

... but this will not work, it looks like there is a limitation. When you think about it makes sense as splat operator is "capturing all remaining arguments" and double splat is "capturing all remaining keyword arguments" therefore mixing them would break expected logic. (I don't have any reference to prove this point doh! )

update 2018 August:

Summary article: https://blog.eq8.eu/til/metaprogramming-ruby-examples.html


In addition to Kevin Conner's answer: block arguments do not support the same semantics as method arguments. You cannot define default arguments or block arguments.

This is only fixed in Ruby 1.9 with the new alternative "stabby lambda" syntax which supports full method argument semantics.

Example:

# Works
def meth(default = :foo, *splat, &block) puts 'Bar'; end

# Doesn't work
define_method :meth { |default = :foo, *splat, &block| puts 'Bar' }

# This works in Ruby 1.9 (modulo typos, I don't actually have it installed)
define_method :meth, ->(default = :foo, *splat, &block) { puts 'Bar' }

With 2.2 you can now use keyword arguments: https://robots.thoughtbot.com/ruby-2-keyword-arguments

define_method(:method) do |refresh: false|
  ..........
end

참고URL : https://stackoverflow.com/questions/89650/how-do-you-pass-arguments-to-define-method

반응형