【问题标题】:A method that applies self to a proc将 self 应用于 proc 的方法
【发布时间】:2012-03-06 20:13:24
【问题描述】:

我想在Object 上定义一个方法,该方法接受一个块并将接收器应用于该块。实现将如下所示:

class Object
    def apply ≺ pr.call(self) end
end

2.apply{|x| x * 3} # => 6

是否已经有标准的方法来做到这一点,或者有一个众所周知的库有类似用途的方法?如果是这样,我不想重新发明轮子。

经常发生在我身上,我有一个方法接受一个可选块,当没有块时,我想返回一些在方法内计算的return_value,但是当有块时,我想要返回应用于块的return_value 的返回值。现在,我有很多行,例如:

def method ..., &pr
  ...
  pr ? pr.call(return_value) : return_value
end

但我想始终如一地写

def method ..., &pr
  ...
  pr ? return_value.apply(&pr) : return_value
end

甚至更好,对apply的定义稍作修改,

def method ..., &pr
  ...
  return_value.apply(&pr)
end

【问题讨论】:

  • 当上面列出的小函数实现了你的目标时,你为什么要引入一个新的依赖?
  • @maerics 如果有内置方式,我想使用它。
  • 为什么不直接使用 lambda? f = ->(x) { x * 3 }; six = f[2]
  • @muistooshort 其实这样不好。
  • 看起来你的积木可能放错了地方。为什么不直接返回值,让调用者用它做他们想做的事?

标签: ruby ruby-1.9.3 proc-object


【解决方案1】:

我猜Object.tap 就是你要找的东西:

"Abc".tap do |str|
  puts str
end

【讨论】:

  • tap 还具有返回您正在点击的对象的副作用,这可能需要也可能不需要(这对于将调用插入方法链很有用),但与原始对象略有不同请求
  • tap 也是 Ruby 1.9 方法,如果存在向后兼容性问题,需要将猴子修补到 Ruby 1.8 中
  • 回复:Ruby 1.9 - 不是真的,它存在于 1.8.7 中。
  • @AleksanderPohl 实际上正如 Gareth 所写,这不是我想要的。
  • 是的,tap 和您的方法(返回值)之间有一点区别。我一开始没有发现它。
【解决方案2】:

这与def apply; yield self; end 不一样吗? – steenslag

@steenslag 是的。这是。我想以self 作为接收者来产生这种效果。 – 锯

这是你的意思吗?

2.instance_eval { * 3 }
# => 6

不幸的是,这不起作用。 instance_eval 只是像接收者是self 一样运行代码。运营商不假定self 是接收者,所以你实际上必须这样写:

2.instance_eval { self * 3 }
# => 6

但是,作为概念证明,这是可能的:

Numeric.send(:define_method, :plus) { |x| self + x }
2.instance_eval { plus 3 }
# => 5

【讨论】:

    【解决方案3】:

    (在阅读 OP 的编辑后)AFAIK 编写此代码的规范方法是:

    def purpose(*args)  #no &bl or &pr
      res = 42 #huge calculation
      return res unless block_given?
      yield res
    end
    
    p purpose(1,2)
    purpose{|n| puts "from the block: #{n}"}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多