代码之家  ›  专栏  ›  技术社区  ›  Dmitry Dmitriev

ruby的不同行为取决于块类型

  •  1
  • Dmitry Dmitriev  · 技术社区  · 7 年前

    很好的一天。 同一段代码的不同行为取决于块语法的类型花括号或do/end。已跳过do/end的块,但没有任何错误通知:

    带花括号的块只是工具和 p 印刷品 one Ruby is a COOL language! 以下内容:

    p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
       "one " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
    }
    

    刚才跳过了do/end中的“相同”代码片段,并且 第页 向我展示 Enumerator <Enumerator: "rubyisacoollanguage":gsub(/(ruby)(is)(a)(cool)(language)/)> :

    p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
        "two " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
    end
    

    我想是因为 第页 第二种情况是消除阻塞。当我加上 第页 在街区内。来自第一个块的数据打印2次,而来自第二个块的数据根本没有被撬起。

    p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
       p "one " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
    }
    p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
        p "two " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
    end
    

    这对我来说是很奇怪和不可预知的行为。没有错误,只是跳过部分代码。为什么会这样?

    3 回复  |  直到 7 年前
        1
  •  5
  •   Sergio Tulentsev    7 年前

    为什么会这样?

    因为{}和do/end具有不同的优先级。{}是“更强的”。如“与最近的方法调用相关联”。所以这个

    p foo {
      something
    }
    

    是这样的。

    p (foo {
      something
    })
    

    做/结束是这样的

    p(foo) do
      something
    end
    

    没有错误,跳过部分代码

    是的,因为ruby的另一个特性。也就是说“你可以把一个块传递给任何方法。因此,使用或忽略这种方法是该方法的责任。 p 不需要一个块,而只是忽略它。

        2
  •  2
  •   tadman    7 年前

    ruby松散的语法规则的问题是,有时它会被块所属的对象绊倒。因为二者都模棱两可 p gsub 可以“拥有”那个街区。这个 do 方法被分配给 第页 ,而 { ... } 方法被固定 GSUB公司 是的。

    这可能是由于某些运算符优先类型规则造成的,尽管由于块本身不是运算符,所以我现在无法确定是否可以找到该特定行为的引用。

    如果存在歧义,最好避免依赖于解释的方式,而是更具体:

    rv = "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
      "two" + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
    end
    
    p rv
    

    在这里 rv = 不能走一个街区,这样它就不会在不经意间抓住它。

    您也可以这样做:

    p(
      "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
        "two" + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
      end
    )
    

    你说得很清楚谁得到了什么。

        3
  •  2
  •   Sam    7 年前

    ruby通常给你两种表达同一事物的方法。这个 block 正在与 p 打电话,不是 gsub 打电话来。

    运算符优先级。