你能用红宝石定义一个内联块吗?

时间:2009-07-29 14:44:45

标签: ruby

是否可以使用ruby在内联语句中定义块?像这样:

tasks.collect(&:title).to_block{|arr| "#{arr.slice(0, arr.length - 1).join(", ")} and #{arr.last}" }

而不是:

titles = tasks.collect(&:title)
"#{titles.slice(0, titles.length - 1).join(", ")} and #{titles.last}"

如果你说tasks.collect(&:title).slice(0, this.length-1)怎么能让'this'引用传递给slice()的完整数组?

基本上我只是想找到一种方法将一个语句返回的对象传递给另一个语句,而不必迭代它。

4 个答案:

答案 0 :(得分:4)

将返回值传递给方法/函数并在返回值上调用方法时,有点令人困惑。做你所描述的方法是:

lambda {|arr| "#{arr.slice(0, arr.length - 1).join(", ")} and #{arr.last}"}.call(tasks.collect(&:title))

如果您想按照您尝试的方式进行操作,最接近的匹配是instance_eval,这使您可以在对象的上下文中运行块。那就是:

tasks.collect(&:title).instance_eval {"#{slice(0, length - 1).join(", ")} and #{last}"}

但是,我不会做其中任何一个,因为它比替代方案更长,更不易读。

答案 1 :(得分:1)

我不确定你要做什么,但是:

  

如果你说tasks.collect(& title).slice(0,this.length-1)怎么能让'this'引用传递给slice()的完整数组?

使用负数:

tasks.collect(&:title)[0..-2]

另外,在:

"#{titles.slice(0, titles.length - 1).join(", ")} and #{titles.last}"

你认为你的引语有些奇怪。

答案 2 :(得分:1)

我真的不明白为什么你会这么想,但是你可以在一个带块的ruby类中添加一个函数,并将自己作为参数传递...

class Object
  def to_block
    yield self
  end
end

此时您可以致电:

tasks.collect(&:title).to_block{|it| it.slice(0, it.length-1)}

当然,不应轻率修改Object类,因为与其他库结合时可能会产生严重后果。

答案 3 :(得分:0)

虽然这里有很多好的答案,但也许你正在寻找一个更符合目标的东西:

class Array
  def andjoin(separator = ', ', word = ' and ')
    case (length)
    when 0
      ''
    when 1
      last.to_s
    when 2
      join(word)
    else
      slice(0, length - 1).join(separator) + word + last.to_s
    end
  end
end

puts %w[ think feel enjoy ].andjoin # => "think, feel and enjoy"
puts %w[ mitchell webb ].andjoin # => "mitchell and webb"
puts %w[ yes ].andjoin # => "yes"

puts %w[ happy fun monkeypatch ].andjoin(', ', ', and ') # => "happy, fun, and monkeypatch"