【问题标题】:Ruby function won't detect do...end blocks [duplicate]Ruby函数不会检测到do ...结束块[重复]
【发布时间】:2015-05-27 17:14:04
【问题描述】:

让我先说我对 Ruby 很陌生。我正在通过几个练习编写我自己的一些可枚举函数的版本。一切都很好,直到它有点停止工作。我不认为我改变了什么。我的功能如下所示:

def my_all?
    return false unless block_given?
    for i in self
        if !yield(i)
            return false
        end
    end
    return true
end

我这样称呼它:

arr = [1,2,3,4]
print arr.my_all? do |num|
    num == num
end

这应该返回 true,因为每个 num 显然都等于它自己。但是我得到一个错误的返回值。经过一番摸索后,我发现 ruby​​ 没有检测到传递给 my_all 的 do...end 块?方法(block_given?返回假)。如果我将 do..end 块更改为单个行括号块,则该方法确实有效,如下所示:

{ |num| num == num}

有人可以告诉我关于 do..end 版本我做错了什么吗?谢谢

【问题讨论】:

  • 由于优先级,该块正在传递给print。添加括号:print (arr.my_all? do |num| ... end).
  • 就是这样,谢谢!

标签: ruby


【解决方案1】:

您可能想查看iterators 而不是使用for 构造。

所以使用.each 看起来像:

def my_all?
    return false unless block_given?
    self.each do |item|
        unless yield(item)
            return false
        end
    end
    return true
end

我还把if ! 换成了unless,因为它读起来更好(只是不要将unlesselse 一起使用>_

【讨论】:

  • return false unless yield(item) 也许,我倾向于劝阻人们不要使用不必要的显式returns,但我知道你只是在复制 OP 的代码。
  • 我不喜欢使用显式的return,除非我从函数中的多个点返回,即在ifcase 内部。但是,是的,我决定不要过多地更改代码,因为如果我给出的示例与原始示例相差太远,最终可能会使 OP 感到困惑。
  • @user3536548 我认为 Dave Newton 指出从函数内部有多个返回点是一个坏主意,句号。最好有一个返回发生的点。更安全、更清洁。
  • @DavidHoelzer 绝对不是我所指出的。我不同意:带有回报的保护条款是有道理的。第二个突破了一个小循环;也有道理。我强烈不同意“只有一次返回”规则,尤其是在这样的短方法中;它读起来很远,far 更干净。例如,stackoverflow.com/a/36714/438992programmers.stackexchange.com/q/118703forums.xkcd.com/viewtopic.php?f=11&t=95359hackerchick.com/2009/02/…
  • @DaveNewton 好吧,我不强制执行它,你提到的短路是一个很好的地方,但很多安全编码人员会不同意:cs.rit.edu/~tmh/courses/SecureCoding/2014/docs/…我经常提供的建议是,如果您要创建多个返回(更具体地说,如果它们散布在整个函数中),那么该函数已经成熟,可以重构为更小的部分了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多