【问题标题】:Ruby ! Methods or Procs红宝石!方法或过程
【发布时间】:2019-06-18 06:19:55
【问题描述】:

我想修改variable,复制methodname! 语法,而不是将新的修改值重新分配给相同的var。我可以用proc 做到这一点吗?我仍在学习procs,并认为它们非常有用,使用得当。

a = "Santol bag 85.88   www.example.com/products/16785
Shaddock    kg  2.94    www.example.com/products/4109
Palm Fig    5kg 94.34   www.example.com/products/23072
Litchee lb  95.85   www.example.com/products/2557"

a = a.split("\n")

linebreak = Proc.new { |text| text.split("\n") }
linebreak![a]

第一次重新分配似乎很麻烦。我想看看我是否可以内联执行它的 proc 版本。这可能吗?

【问题讨论】:

  • 使用! 不是特殊语法,它是一种命名约定,只能在声明函数时使用——因此linebreak! = Proc.new... 会导致语法错误。您也不能一般Proc 改变超出范围的状态。

标签: ruby block proc


【解决方案1】:

这肯定是可能的,你只需要就地修改字符串

linebreak = ->(text) { text.replace text.split("\n").join(",") }
a = "foo\nbar"
linebreak[a]
#⇒ "foo,bar"
a
#⇒ "foo,bar"

不可能的是,在适当的位置更改类,这就是split 不起作用的原因(在字符串上调用,它返回一个数组。)

【讨论】:

  • 这确实有效,但需要注意的是,这不是一个很好的设计选择因为它会改变状态并且名称中没有爆炸 (!) - - 这可能会让未来的程序员相信这是一个没有副作用的函数。
  • @Jules 那是红宝石;一切都应该被认为是可变的。此外,您可能会注意到上面使用的 stdlib 中的 String#replace 名称中没有 bang。
  • !用于方法的约定,仅用于突变。例如。 Process::exit! 与突变无关,String#clear 没有爆炸。
【解决方案2】:

methodname! 只是一个约定——通常有两种风味的相同方法——一种没有爆炸,一种有爆炸。如果你想要一个 proc 来改变它的参数,你需要使用 mutating 方法来实现它。

在这种情况下这是不可能的,因为您正试图将字符串转换为数组。您必须重新分配变量:

linebreak = Proc.new { |text| text.split("\n") }
a = linebreak.call(a)

【讨论】:

  • 所以重新分配给新类型是警告?
  • ruby 中的参数作为值传递给方法和过程,因此您不能重新分配它们。见this detailed answer
猜你喜欢
  • 2014-12-05
  • 2015-03-21
  • 1970-01-01
  • 2011-02-28
  • 2013-03-19
  • 2010-09-08
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多