调用rubyclass方法和存储在proc中的参数

Call ruby class method and parameters stored in proc

我有一个 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

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

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?是否需要延迟评估方法参数?

已接受的答案已经显示了可能性。我只是想分享一下,您也可以从 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 method is available in Rails and recently Ruby also supports this from Ruby 3.00