我有这个简单的Ruby 代码.它是"代理模式"的实现.在最后一行出现故障

class ExecuteProxy
    def initialize(controller_object)
      @controller_object = controller_object
    end

    def method_missing(method, *args)
      args.empty? ? @controller_object.send(method) : @controller_object.send(method, *args)
      return
    end
end

class MyClass
    def no_arghuments
        puts "no_arghuments"
    end
    def one_argument(arg1)
        puts "one_argument #{arg1}"
    end
    def one_argument_and_named(arg1, count:1)
        puts "one_argument #{arg1} and count #{count}"
    end
end

obj = MyClass.new
proxy = ExecuteProxy.new(obj)

proxy.no_arghuments
proxy.one_argument("test")
proxy.one_argument_and_named("test2")
proxy.one_argument_and_named("test2", count:2)

输出

no_arghuments
one_argument test
one_argument test2 and count 1
test1.rb:20:in `one_argument_and_named': wrong number of arguments (given 2, expected 1) (ArgumentError)
    from test1.rb:8:in `method_missing'
    from test1.rb:31:in `<main>'

如何才能解决这个问题?如果一个方法具有普通参数+命名参数,我如何使用Send将执行传递给不同的类?

最新消息.有工作代码,答案有帮助,谢谢.

class ExecuteProxy
    def initialize(controller_object)
      @controller_object = controller_object
    end

    def method_missing(method, *args, **kw)
      @controller_object.send(method, *args, **kw)
      return
    end
end

class MyClass
    def no_arghuments
        puts "no_arghuments"
    end
    def one_argument(arg1)
        puts "one_argument #{arg1}"
    end
    def one_argument_and_named(arg1, count:1)
        puts "one_argument #{arg1} and count #{count}"
    end
    def only_named(count:, str:"")
        puts "only_named count #{count}, str: #{str}"
    end
    def manyarguments_and_named_args(arg1, arg2, arg3 = "def", count:1, some_other:"d")
        puts "manyarguments_and_named_args #{arg1}, #{arg2}, #{arg3} and count #{count}, some_other #{some_other}"
    end
end

obj = MyClass.new
proxy = ExecuteProxy.new(obj)

proxy.no_arghuments
proxy.one_argument("test")
proxy.one_argument_and_named("test2")
proxy.one_argument_and_named("test2", count:2)
proxy.only_named(count:3)
proxy.only_named(count:3,str:"string")
proxy.manyarguments_and_named_args("a1","a2")
proxy.manyarguments_and_named_args("a1","a2", "s3")
proxy.manyarguments_and_named_args("a1","a2", count:4)
proxy.manyarguments_and_named_args("a1","a2", count:4, some_other:nil)

输出

no_arghuments
one_argument test
one_argument test2 and count 1
one_argument test2 and count 2
only_named count 3, str: 
only_named count 3, str: string
manyarguments_and_named_args a1, a2, def and count 1, some_other d
manyarguments_and_named_args a1, a2, s3 and count 1, some_other d
manyarguments_and_named_args a1, a2, def and count 4, some_other d
manyarguments_and_named_args a1, a2, def and count 4, some_other 

推荐答案

当您将显式散列作为最后一个参数传递时,它不能算作关键字参数,您必须对它们进行双重处理:

def one_argument_and_named(arg1, count: 1)
  puts "one_argument #{arg1} and count #{count}"
end

one_argument_and_named("test2", count: 2)      # good
one_argument_and_named(*["test2", count: 2])   # bad
one_argument_and_named("test2", {count: 2})    # bad
one_argument_and_named("test2", **{count: 2})  # good

你不必判断你是否有参数,如果是空的,它们就会消失:

def method_missing(method, *args, **kw)
  @controller_object.send(method, *args, **kw)
end

# depending on your ruby version you could do this
# only if you don't need intermidiate access to args or kw
def method_missing(method, *, **)
  @controller_object.send(method, *, **)
end
# or
def method_missing(method, ...)
  @controller_object.send(method, ...)
end

Ruby相关问答推荐

Ruby 匹配第一次出现的字符串以进行 gsub 替换

如何过滤散列数组以仅获取另一个数组中的键?

ActiveRecord::AdapterNotSpecified 数据库配置未指定适配器

Ruby 符号到类

Simple_form:删除带有标签的内联复选框的外部标签

Ruby:如何卸载设计(uninstall Devise)?

判断字符串是否包含Ruby数组中的任何子字符串

根据另一个数组的元素对数组进行排序

Ruby 中的关联数组

Rails:Date.today 是 UTC 吗?

Ruby数组each_slice_with_index?

从 Ruby 中的字符串创建不区分大小写的正则表达式

如何按字母顺序排列忽略大小写的数组?

从类对象获取类位置

条件子句中的赋值是好的Ruby风格吗?

Ruby 中的文件打开模式

如何使用 RVM 更新 Ruby 解释器?

野外的好黄瓜例子?

Ruby中的urldecode?

如何判断数组是否有重复项?