【问题标题】:How can I define a method which arguments have no type in Ruby [closed]如何在Ruby中定义一个参数没有类型的方法[关闭]
【发布时间】:2014-01-31 13:53:06
【问题描述】:

如果我定义了一个方法:

def weird_method(first_argument, second_argument)
  #code here
end

这样我就可以传递如下参数:1、:digit、'some'、"more"(Fixnum、Symbol、String 等),但是如果我只想传递这个:argument1、argument2 ,我的意思是没有类型并且看起来像局部变量但实际上不是的值。我怎样才能以某种方式接受它们并在方法体中使用它们?

PS:我需要它来实现一个小的 DSL,当块被传递时,它可以在 .isntance_eval 中做那种事情

Something.with_method do
 sum 1, 2         #(I can implement it)
 play volleyball  #(I can NOT implement it)
 swim further     #(I can NOT implement it)
 eat "a lot"      #(I can implement it)
end

编辑:

一切都可以进行排球进一步。我只是举了一个例子。 sum、play、swim、eat 是 Something 类中定义的方法。

【问题讨论】:

  • 没有没有类型的值这样的东西,volleyball 在你的例子中是什么?方法?变量?
  • 如果你想传递另一个变量或方法的名称,那么通常使用StringSymbol,因为这些可以与@一起使用987654326@、define_method 和其他 Ruby 元编程方法。
  • @mechanicalfish sum, play, swin, eat 都是 my Something 中的方法。争论就是问题。
  • 这个方法对我来说很奇怪

标签: ruby methods arguments dsl


【解决方案1】:

符号的存在正是您在此处谈论的目的:它们是仅对自身进行评估的值。符号:volleyball 就是符号:volleyball,这就是它的全部。它没有其他价值或意义。

如果您只是为了审美目的而希望它以不同的方式阅读,您最好的选择可能是定义返回适当符号的方法(例如def volleyball() :volleyball end)。但这似乎不合时宜。

如果您真的希望人们能够发送几乎任何还不是方法的东西,您可以按照def method_missing(m, *args) m.to_sym end 的方式实现method_missing。但在我能想到的大多数情况下,我真的觉得这种设计很尴尬。

【讨论】:

    【解决方案2】:
    class Something
      attr_reader :callstack
    
      def initialize
        @callstack = {}
      end
    
      def self.with_method &block
       self.new.instance_exec &block
      end
    
      def method_missing method, *params
        params.empty? ? method : callstack[method] = params
      end
    end
    
    Something.with_method do
     sum 1, 2
     play volleyball
     swim further
     eat "a lot"
    
     puts callstack # => {:sum=>[1, 2], :play=>[:volleyball], :swim=>[:further], :eat=>["a lot"]}
    end
    

    这有帮助吗?

    【讨论】:

    • 请看,排球等只是示例。你的逻辑说我只能通过排球和进一步。如果我想将足球、垒球、棒球等传给比赛方法怎么办?一切都可以在 play 方法参数上进行
    • 我已经更新了答案,这就是你要找的吗?
    • 好吧,这不是调用堆栈。另外,当我启动您的代码时,它只接受 sum 和 eat 的参数。玩耍和游泳似乎“毫无争议”。
    • 确实如此,而且他们并非毫无争议。 volleyballfurther 是这里的参数。我建议重新考虑你的问题,因为显然你不知道你在问什么。
    • 好问题。我会尝试改进或拯救NameError
    【解决方案3】:

    您必须将对象作为方法参数传递。您试图通过传递任意未定义的名称来完成什么功能?您总是可以将它们作为字符串传递,然后使用该字符串来使用方法内的文本。

    例如。

    def self.methodname(arg1, arg2)
      arg1 = arg2
    end
    
    Class.methodname("greeting","hello")
    

    将变量greeting设置为等于'hello'

    【讨论】:

    • Sam,您需要在答案中格式化代码。突出显示它并单击 {} 图标或用反引号(反斜单引号,位于我的 Mac 键盘的左上角)包围代码。 (好多了!)
    • 它的想法是实现一个仅使用 4 个寄存器的简单汇编程序,并且在某些时候我可以放置标签,跳转到代码中的命令,但很难解释它。如果像这样传递参数,我只需要能够接受它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多