0

这是我想做的:

class Directory
  def doSomething
  end

  def subs
    # => an array of Directory objects
  end

  def recursively (method)
    self.subs.each do |sub|
      sub.method
      sub.recursively method
    end
  end
end

cd = Directory.new

cd.recursively 'doSomething'
# ...and extra points if theres a way to:
cd.recursively.doSomething

从这个角度来看,我正在创建一个小脚本,它将更改目录中的文件及其所有子目录。这些子目录将只是扩展Directory对象。

那么有没有办法将一个方法作为另一个方法的参数传递呢?

4

4 回答 4

1

您可以使用Object#send, 其中method是表示方法名称的字符串或符号,如您的第一个示例中所示。只需将您的更改#recursively为:

def recursively(method)
  subs.each do |sub|
    sub.send method
    sub.recursively method
  end
end

更新

对于您的“加分”问题,并接受 megas 的回答,这里是基于 Enumerator 的方法的尝试。将其放入您的目录:

def recursively
  Enumerator.new do |y|
    subs.each do |sub|
      y.yield sub
      sub.recursively.each do |e|
        y.yield e
      end
    end
  end
end

并这样称呼它:

cd.recursively.each { |d| d.doSomething }
于 2012-05-18T19:18:03.413 回答
1

是的,你可以这样做——

class Directory
    def doSomething
    end

    def subs
        # => an array of Directory objects
    end

    def recursively (method)
        self.subs.each do |sub|
            sub.method.call
            sub.recursively method
        end
    end
end

dir = Directory.new
ds = dir.method :doSomething

dir.recursively ds
于 2012-05-18T19:19:01.610 回答
1

我认为这里应该是each来自 Enumerable 模块的专门方法。当你实现each方法时,Enumerable 模块会提供很多方便的方法map, drop,诸如此类。

class Directory
  include Enumerable

  def initialize
    # here you should build @objects - a whole list of all objects in 
    # the current direcory and its subdirectories.
    @objects = ....
  end

  def each         
    if block_given?
      @objects.each { |e| yield(e) }
    else
      Enumerator.new(self, :each)
    end
  end

  ...
end

然后您可以以优雅的方式迭代所有对象:

@directory = Directory.new('start_directory')

@directory.each do |object|
  puts object.size # this will prints the sizes for all objects in directory
  object.do_some_job # this will call method on object for all your objects
end

这将为目录中的所有对象提供一系列大小

@directory.map { |object| object.size } #=> [435435,64545,23434,45645, ...]

附加示例:

例如,您需要获取包含所有对象的索引和大小的列表

@directory.each_with_index.map { |object, index| [index, object.size] }

#=> [ [0,43543], [1,33534], [2,34543564], [3,345435], ...]
于 2012-05-18T19:25:00.267 回答
0

看看这是否能让你朝着正确的方向前进:

module Recursion
  def recursively(&block)
    output = block.call(self)
    output.recursively(&block) unless output.nil?
  end
end

class Number
  include Recursion

  def initialize(value)
    @value = value
  end

  def next
    @value > 0 ? Number.new(@value - 1) : nil
  end

  def print
    puts @value
    self.next
  end
end

Number.new(10).recursively(&:print)
于 2012-05-18T19:15:47.977 回答