Ruby 带有可选选项和 &block 参数的方法
Ruby method with optional options and &block parameter
你好
是否可以将可选属性和块作为参数
用于方法调用?
示例:我必须打电话
method(foo, foo: bar, -> { do_something }
并尝试使用
def method(foo, *bar, &block)
end
至于我的理解,块总是必须在最后位置?
经过一些研究,我发现一元 (?) *
似乎是为了
阵列。由于我尝试传递 Hash
我将代码更改为
def method(foo, bar={}, &block)
end
但这也不起作用。我猜是因为他不能
找出栏结束和块开始的位置。
有什么想法或建议吗?提前谢谢你
附加:只是出于好奇我为什么需要这个。我们有一个大 json
schema 运行 并有一个小的 DSL 构建 json 从
模型定义。无需详细介绍,我们希望
实施 exportable_scopes.
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 和 incense);
- 提供时间强制关键字参数;
- 省略了姿势可选关键字参数;
- 通过 **periods 参数传递了几个额外的关键字参数(period1:"morning",period2:"afternoon");
- 通过 &b 参数传递了块 { puts "Hello from inside the block" };
请注意上面的服务器示例仅用于说明混合不同类型参数的可能性。在实际代码中构建这样的方法将是一种不好的做法。如果一个方法需要那么多参数,最好将它拆分成更小的方法。如果绝对有必要将这么多数据传递给一个方法,我们可能应该创建一个 class 来以更有条理的方式存储数据,然后将那个 class 的实例作为单个参数。
你好
是否可以将可选属性和块作为参数 用于方法调用?
示例:我必须打电话
method(foo, foo: bar, -> { do_something }
并尝试使用
def method(foo, *bar, &block) end
至于我的理解,块总是必须在最后位置?
经过一些研究,我发现一元 (?)
*
似乎是为了 阵列。由于我尝试传递Hash
我将代码更改为def method(foo, bar={}, &block) end
但这也不起作用。我猜是因为他不能 找出栏结束和块开始的位置。
有什么想法或建议吗?提前谢谢你
附加:只是出于好奇我为什么需要这个。我们有一个大 json schema 运行 并有一个小的 DSL 构建 json 从 模型定义。无需详细介绍,我们希望 实施 exportable_scopes.
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 和 incense);
- 提供时间强制关键字参数;
- 省略了姿势可选关键字参数;
- 通过 **periods 参数传递了几个额外的关键字参数(period1:"morning",period2:"afternoon");
- 通过 &b 参数传递了块 { puts "Hello from inside the block" };
请注意上面的服务器示例仅用于说明混合不同类型参数的可能性。在实际代码中构建这样的方法将是一种不好的做法。如果一个方法需要那么多参数,最好将它拆分成更小的方法。如果绝对有必要将这么多数据传递给一个方法,我们可能应该创建一个 class 来以更有条理的方式存储数据,然后将那个 class 的实例作为单个参数。