【问题标题】:Call ruby class method and parameters stored in proc调用存储在proc中的ruby类方法和参数
【发布时间】:2021-05-04 15:41:13
【问题描述】:

我有一个proc,设置如下:

@method_to_call = Proc.new { || {:method=>'some_method',:user_id=>1 } }

现在我想用参数user_id调用方法some_method

def some_method(user_id)
 # does something
end

关键是proc也可以有不同的参数,例如:

@method_to_call = Proc.new { || {:method=>'some_method_two',:user_id=>1, :app_id=>2 } }

会调用:

def some_method_two(user_id,app_id)
  # do something
end

我目前有一个方法如图:

def handle_action
  parts = @method_to_call.call
  curr_method = parts[:method]
  if curr_method == "some_method"
     some_method parts[:user_id]
  elsif curr_method == "some_method_two"
     some_method_two parts[:user_id], parts[:app_id]
  end
end

但我想要...

def handle_action
   # call method in proc and pass parameters stored in proc dynamically
end

【问题讨论】:

    标签: ruby proc


    【解决方案1】:

    如果您将 procs 结构化为方法名称和参数列表:

    Proc.new { ['some_method', [1]] }
    Proc.new { ['some_method_two', [1, 2]] }
    

    你可以这样做

    def handle_action
      method, args = @method_to_call.call
    
      public_send(method, *args)
    end
    

    如果这有损于理解(鉴于 user_idapp_id 不再记录),您始终可以将这些方法转换为使用关键字参数,然后重写为

    def some_method_two(user_id:, app_id:)
      do_something
    end
    
    @method_to_call = Proc.new { ['some_method_two', { user_id: 1, app_id: 2 }] }
    
    def handle_action
      method, args = @method_to_call.call
    
      public_send(method, **args)
    end
    

    出于兴趣,您有什么理由首先需要使用 procs 吗?是否需要延迟对方法参数的评估?

    【讨论】:

    • 使用提供的规格的闭包对我们来说很方便。
    【解决方案2】:

    接受的答案已经显示了可能的情况。我只是想分享一下,你也可以从 Proc 内部调用方法。

    @method_to_call = Proc.new do |**kwargs|
      some_method(kwargs.except(:method)) if kwargs[:method] == 'some_method'
      some_method_2(kwargs.except(:method)) if kwargs[:method] == 'some_method_2'
    end
    
    def some_method(user_id:)
      puts "User ID: #{user_id}"
    end
    
    def some_method_2(user_id:, app_id:)
      puts "User ID: #{user_id}, App ID: #{app_id}"
    end
    
    @method_to_call.call({ method: 'some_method', user_id: 1 })
    @method_to_call.call({ method: 'some_method_2', user_id: 1, app_id: 2 })
    

    输出:

    User ID: 1
    User ID: 1, App ID: 2
    

    请注意: Hash#except 方法在 Rails 中可用,最近 Ruby 也支持 Ruby 3.00

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多