【问题标题】:Ruby Proc with Parameter带参数的 Ruby Proc
【发布时间】:2019-08-07 19:26:45
【问题描述】:

我正在尝试将参数发送到 Ruby proc

p1 = [54, 21, 45, 76, 12, 11, 67, 5]

qualify = proc { |age, other| age > other }

puts p1.select(&qualify(30))

这是我得到的错误:

undefined method `qualify' for main:Object

年龄来自array的迭代,我想让最后一个parameter30)进入proc

proc 是用于此目的的正确工具吗?我是新手。我不清楚如何在那里获得parameter

【问题讨论】:

  • 期望的返回值是多少?
  • 我想将“30”作为一个变量,用于返回值超过 30 的数组。但这不仅仅是这个例子。我想要通用的procs,我可以将params 扔到。
  • 是的。但我正在尝试实现proc 版本,以便学习它们。
  • 你想在这里做什么,咖喱?
  • 我不知道这个词。我认为将参数放入 proc 是很正常的事情。我正在查看其他回复。

标签: ruby lambda proc


【解决方案1】:

为了将qualify 用作select 谓词,您需要通过部分应用来减少它的arity(接受参数的数量)。换句话说 - 您需要一个将other 设置为30 的新进程。可以用Method#curry完成,但是需要改变参数的顺序:

qualify = proc { |other, age| age > other }
qualify.curry.call(30).call(10)
# => false
qualify.curry.call(30).call(40)
#=> true

我为了能够使用& 传递这个过程来选择,你需要分配它以便它在主对象中可用,例如通过将其分配给实例变量:

@qualify_30 = qualify.curry.call(30)

现在你可以打电话了:

p1.select{ |age| @qualify_30.call(age)  }
# => [54, 45, 76, 67]

或:

p1.select(&@qualify_30)
# => [54, 45, 76, 67]

或内联:

p1.select(&qualify.curry.call(30))
# => [54, 45, 76, 67]

【讨论】:

  • 最后你可以做 p1.select(&@qualify_30) 或者它可以像p1.select(&qualify.curry.call(30)) 那样内联完成
  • 除非需要持久化,否则不需要使用实例变量,如果需要,可以改为常量。您还可以使用更短的符号:@qualify_30[40],其中[]call 的别名。
【解决方案2】:

简单的方法是改变你的定义:

p1 = [54, 21, 45, 76, 12, 11, 67, 5]

qualify = proc { |age| age > 30 }

puts p1.select(&qualify).join(',')

通过将30 移动到qualify 过程中,您已经在该条件下烘焙,它不再是动态的。请记住,可以与速记 &: 技巧一起使用的唯一方法是零参数方法,或在 proc 上带有 & 的单参数方法。

您还可以使用 闭包 来公开比较变量:

p1 = [54, 21, 45, 76, 12, 11, 67, 5]

required = 30

qualify = proc { |age| age > required }

puts p1.select(&qualify).join(',')

required = 10

puts p1.select(&qualify).join(',')

更好的方法是把它拼出来,这就是 Ruby 的全部意义所在。这里以更惯用的形式:

p1 = [54, 21, 45, 76, 12, 11, 67, 5]

puts p1.select { |age| age > 30 }

中间 Proc 的唯一原因是,如果您出于某种原因想要将其保存在某个地方并在以后重新使用它。

【讨论】:

  • “唯一可以使用的方法......是零参数的” - 但qualify 这里的元数为 1。它甚至不是一种方法。也许,这个断言可以以某种方式改写。
  • 当然可以使用带参数的方法。因为& 看不到方法调用。只有它的结果。 repl.it/repls/EuphoricPunctualBetatest
  • 我看到你已经从parameter 的角色中删除了所需的角色,所以在我看来,这实际上只是另一个硬编码的proc。不太尊重DRY。我认为输入param 会很容易。
【解决方案3】:

在 proc 本身中使用 select 语句,以便 proc 计算并返回一个数组。

2.1.5 :119 >   qualify = proc { |age_array, age_limit| age_array.select { |age| age > age_limit } }
 => #<Proc:0xe7bc2cc@(irb):119> 
2.1.5 :120 > 
2.1.5 :121 >   
2.1.5 :122 >   qualify.call(p1, 30)
 => [54, 45, 76, 67] 

【讨论】:

  • 优秀。因此,您只需将数组作为变量本身扔到 proc 中。我被困在迭代器上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-11
  • 2023-03-19
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 2012-01-12
相关资源
最近更新 更多