Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有可选选项和&;的Ruby方法;块参数_Ruby_Methods_Parameters_Unary Operator - Fatal编程技术网

带有可选选项和&;的Ruby方法;块参数

带有可选选项和&;的Ruby方法;块参数,ruby,methods,parameters,unary-operator,Ruby,Methods,Parameters,Unary Operator,嘿 是否可以将可选属性和块作为参数 对于方法调用 我必须打电话 method(foo, foo: bar, -> { do_something } 并尝试了它 def method(foo, *bar, &block) end 就我的理解而言,挡块总是在最后一个位置 经过一点研究,我发现一元(?)似乎是 数组。因为我试图传递一个散列,所以我将代码更改为 def method(foo, bar={}, &block) end 但这也不管用。我想是因为他不能 找出条的终点

是否可以将可选属性和块作为参数 对于方法调用

我必须打电话

method(foo, foo: bar, -> { do_something }
并尝试了它

def method(foo, *bar, &block)
end
就我的理解而言,挡块总是在最后一个位置

经过一点研究,我发现一元(?)似乎是 数组。因为我试图传递一个
散列
,所以我将代码更改为

def method(foo, bar={}, &block)
end
但这也不管用。我想是因为他不能 找出条的终点和块的起点

有什么想法或建议吗?先谢谢你

附加:只是出于好奇,为什么我需要这个。我们有一个大问题 模式正在运行,并且有一个小型DSL,用于从 模型定义。没有太多细节,我们想 实现可导出的\u作用域

class FooBar
  exportable_scope :some_scope, title: 'Some Scope', -> { rewhere archived: true }
end
在某些初始值设定项上,这应该发生:

def exportable_scope scope, attributes, &block
  scope scope block
  if attributes.any?
    attributes.each do |attribute|
      exportable_schema.scopes[scope] = attribute
    end
  else
    exportable_schema.scopes[scope] = {title: scope}
  end
end
这很好,我只需要一个方法的提示 参数

是的,这是可能的

当混合不同类型的参数时,它们必须以特定顺序包含在方法定义中:

  • 位置参数(必需和可选)和单个splat参数,以任意顺序排列
  • 关键字参数(必需和可选),按任意顺序排列
  • 双splat参数
  • 块参数(前缀为&) 上面的顺序有些灵活。我们可以定义一个方法,并以一个splat参数开始参数列表,然后是几个可选的位置参数,依此类推。尽管Ruby允许这样做,但这通常是一种非常糟糕的做法,因为代码很难阅读,甚至更难调试。通常最好使用以下顺序:

  • 所需的位置参数
  • 可选位置参数(具有默认值)
  • 单splat参数
  • 关键字参数(必选,顺序无关)
  • 双splat参数
  • 显式块参数(前缀为&)
  • 例如:

    def meditate cushion, meditation="kinhin", *room_items, time: , posture: "kekkafuza", **periods, &b
        puts "We are practicing #{meditation}, for #{time} minutes, in the #{posture} posture (ouch, my knees!)."
        puts "Room items: #{room_items}"
        puts "Periods: #{periods}"
        b.call # Run the proc received through the &b parameter
    end
    
    meditate("zafu", "zazen", "zabuton", "incense", time: 40, period1: "morning", period2: "afternoon" ) { puts "Hello from inside the block" }
    
    # Output:
    We are practicing zazen, for 40 minutes, in the kekkafuza posture (ouch, my knees!).
    Room items: ["zabuton", "incense"]
    Periods: {:period1=>"morning", :period2=>"afternoon"}
    Hello from inside the block
    
    请注意,调用该方法时,我们有:

    • 提供了缓冲的强制性位置论证
    • 覆盖可选位置参数的默认值
    • 通过*room_items参数传递了两个额外的位置参数(zabuton和As香)
    • 提供了时间强制关键字参数
    • 省略了姿态可选关键字参数
    • 通过**periods参数传递了两个额外的关键字参数(period1:“morning”,period2:“午后”)
    • 通过&b参数传递块{put“Hello from the block”}

    请注意上面的示例服务器只是为了说明混合不同类型参数的可能性。在实际代码中构建这样的方法将是一种糟糕的做法。如果一个方法需要那么多参数,那么最好将其拆分为更小的方法。如果绝对有必要将这么多的数据传递给单个方法,我们可能应该创建一个类以更有序的方式存储数据,然后将该类的一个实例作为单个参数传递给该方法。

    I ting,您可以使用
    exportable\u scope(:some\u scope,title:'some scope'){rewhere archived:true}
    。您不需要像参数一样发送块。我认为您混淆了传递块和传递可调用对象(lambda)作为参数,这是ActiveRecord
    .scope
    希望接收的。作用域的主体是必需的,因此您可以将方法签名更改为
    exportable_作用域(name,body,attributes={})
    并调用
    scope name,body
    。请查看
    .scope
    此处的定义:<代码>可导出的范围:一些范围,->{rewhere archived:true},标题:“一些范围”。