`block_given?`渲染`&block`参数是否可选?

问题描述 投票:0回答:2

我对以下内容感到满意:

def some_def(foo, &block)
    puts "block utilized below"
    block.call(foo)
end

def some_other_def(bar)
    puts "using yield below"
    yield bar
    puts "and back into the method"
end

所以我学会了将块(和procs)与yield关键字分开。

但是,我遇到了以下代码:

# ./open_file.rb

class File
    def self.open(name, mode, &block)
        file = new(name, mode)
        return file unless block_given?
        yield(file)
    ensure
        file.close
    end
end

当我在irb中执行此代码时,参数&block似乎无关紧要:

irb -r ./file.open.rb

并做一些类似的事情:

File.open('foo.txt','r') {|f| puts f}

Qazxswpoi是否可选&block

block_given?
ruby yield ruby-block
2个回答
3
投票

通常,如果需要将块传递给另一个方法(例如在此示例中),则只使用return file unless block_given? 参数:

&block

或者这个真实版本的def m(&block) some_array.map(&block) end

Enumerable#sum from Rails

在任何一种情况下,调用该方法的块都与另一个方法调用一起使用,因此您需要一种方法来引用该块(即名称)。

所以def sum(identity = nil, &block) if block_given? map(&block).sum(identity) else sum = identity ? inject(identity, :+) : inject(:+) sum || identity || 0 end end / block_given?yield有不同的用途。能够调用&block不会使block_given?多余,并且,如上面的&block实现,它们甚至可以一起使用。


1
投票

方法签名中的#sum接受一个块,将其转换为proc,并将其分配给名为&block的变量。如果没有提供块,则block被指定为block

是否在方法定义中使用参数nil并不重要,就像在以下定义中是否使用普通方法参数block无关紧要:

bar

但是,接受块作为参数而不使用它是多余的并且浪费资源。对于程序员明确指出该方法接受块可能仍然有意义。

使用def foo(bar); end 与所有这些无关。它与块是否已被block_given?作为参数接受无关。无论&如何,它都直接指向块。

© www.soinside.com 2019 - 2024. All rights reserved.