Ruby 是否可以声明块为默认值的方法?
我想写一个方法,它接受一个块,如果没有给定的块,它应该使用一个默认块。所以我想要这样的东西:Ruby 是否可以声明块为默认值的方法?,ruby,lambda,block,Ruby,Lambda,Block,我想写一个方法,它接受一个块,如果没有给定的块,它应该使用一个默认块。所以我想要这样的东西: def say_hello(name, &block = ->(name) { puts "Hi, #{name}" }) # do something end 但是当我尝试这样做时,我得到了语法错误 我知道我可以用电脑解决我的问题。但我对第一种方法感兴趣。 我遗漏了什么或者这是不可能的吗?你可以用普通的lambda来做 def say_hello(name, block = -&
def say_hello(name, &block = ->(name) { puts "Hi, #{name}" })
# do something
end
但是当我尝试这样做时,我得到了语法错误
我知道我可以用电脑解决我的问题。但我对第一种方法感兴趣。
我遗漏了什么或者这是不可能的吗?你可以用普通的lambda来做
def say_hello(name, block = ->(name) { puts "Hi, #{name}" })
block.call(name)
end
say_hello("Sergio")
say_hello("Ivan", ->(name) { puts "Where are you from, #{name}?"})
# >> Hi, Sergio
# >> Where are you from, Ivan?
但是,不确定是否可以使用块来执行此操作。块不是普通参数。您不能在方法定义中声明默认块,但是如果没有指定自定义块,您可以使用一些小技巧来使用自定义块
def say_hello(name)
block = block_given? ? Proc.new : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
# This example uses a custom block
say_hello('weppos') { |name| puts "Hello, #{name}!" }
# => Hello, weppos!
# This example fallbacks to the default
say_hello('weppos')
# => Hi, weppos!
让我解释一下。让我们从一个更可读的版本开始
def say_hello(name, &block)
block = block ? block : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
定义接受块的方法,然后检查是否定义了块。如果不是,则指定一个自定义块。最后,执行块
让我们把它增强一点。你可以使用block_吗?检查是否通过了块
def say_hello(name, &block)
block = block_given? ? block : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
这还允许您跳过方法定义中的块声明(&block
)
def say_hello(name)
if block_given?
yield name
else
# This is rendundant, but it's for clarity
block = ->(name) { puts "Hi, #{name}" }
block.call(name)
end
end
但是,此时,您还可以使用Proc.new
将块分配给变量
def say_hello(name)
block = block_given? ? Proc.new : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
最后一句话,我试图理解这种方法何时才有意义。在大多数情况下,您可能可以将代码包装在类或模块中,并将其作为参数传递。可能更好。不,不能在方法定义中提供默认块值。但是,您可以通过在方法主体内使用
block\u given?
实现等效行为,如下所示:
def say_hello(name, &block)
block = ->(name) { puts "Hi, #{name}" } unless block_given?
# do something
end
但是,在这种情况下,您不能利用
yield
调用传入的任何块,因为在默认情况下它不在那里。您必须调用块
Proc
对象,如块。(名称)
一些答案建议使用块(给定)
,但由于在给定块时,块不可能是nil
或false
,因此您可以简单地使用| |=
def say_hello(name, &block)
block ||= ->(name){puts "Hi, #{name}"}
# do something
end
当我发布我的答案时,没有看到你的答案。如果使用
&block
作为参数,则如果未传递块,则不必将block
定义为Proc.new
,因为Ruby会为您处理。对吗?我必须写下我知道什么是block\u给定的?
do.)虽然答案很棒。我目前正在玩的东西需要在method\u missing
上声明一个方法。例如foobar{| x | puts x}
将向当前对象类添加一个方法foobar(x)
。您是否也必须切换访问块的方法以避免yield
?@PeterAlfvin我不明白您的意思。如果调用中没有提供块,那么yield
语句将无法工作。您必须使用block.call(…)
或类似的方法调用它。@PeterAlfvin没错。那么,收益率如何相关?你想告诉我什么?我想告诉你,如果调用方不提供值,这种为块
赋值的技术与为&block
提供默认值相比,不是一种透明的替代方法(即提供一个“默认块”,以便在调用方不提供时使用)。OP需要知道,如果他以前使用了yield
,他需要更改他的代码(即#do something
)以使用这种替代方法。