2

我有这个代码:

class Note < Struct.new :value
  def to_s
    value.to_s
  end
  def self.use_new(arg)
    Note.new arg
  end
end

class Chord
  def initialize(arr)
    @arr = arr
  end

  def play
    @arr.join('-')
  end
end
new_method = Note.singleton_method(:use_new)
chords = %w{ G Bb Dd E }
c = Chord.new(chords.map(:new_method))
puts c.play

现在我知道我不必用地图做这个,我可以简单地使用map {|n| Note.new n}

但我想知道如何做到这一点。下面说 Note 没有一个名为 singleton_method 的方法。当我尝试使用实例方法(定义中没有 self)时,它说该方法不存在。请指教。

4

2 回答 2

3

你为什么要一个UnboundMethod?您可以明智地使用UnboundMethod. 特别是,你不能call。您唯一能做的就是bind将它添加到您从中获取它的实例module以获取 bound Method。然而,在这种情况下,有module问题的是Note's 单例类,它无论如何只有一个实例,所以你只能bind将它用于Note. 因此,您不妨一开始就受到约束Method

new_method = Note.method(:use_new)
chords = %w{ G Bb Dd E }
c = Chord.new(chords.map(&new_method)) # BTW: you had a typo here
puts c.play

我也不明白你的目的Note::use_new是什么。它只是一个无操作包装器Note::new,所以它也可以是一个alias_method替代品。或者,更好的是,只需将其删除,它没有任何用途:

new_method = Note.method(:new)
chords = %w{ G Bb Dd E }
c = Chord.new(chords.map(&new_method)) # BTW: you had a typo here
puts c.play

singleton_method如果您想确保获得单例方法,您也可以使用:

new_method = Note.singleton_method(:use_new)
chords = %w{ G Bb Dd E }
c = Chord.new(chords.map(&new_method)) # BTW: you had a typo here
puts c.play

如果你真的坚持要得到 an UnboundMethod,那么你必须先得到bind它,然后才能使用它,并且你必须从单例类中得到它,因为singleton_method返回 aMethod不是 an UnboundMethod

new_method = Note.singleton_class.instance_method(:use_new)
chords = %w{ G Bb Dd E }
c = Chord.new(chords.map(&new_method.bind(Note)))
puts c.play
于 2013-05-31T00:31:33.427 回答
3

尝试这个:

new_method = (class << Note; self; end).instance_method(:use_new)

这解决了主要问题,尽管还有其他一些问题。

于 2013-05-31T00:22:42.163 回答