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

アップデート

あなたの「余分なポイント」の質問とメガの答えを拾うために、ここに列挙子ベースのアプローチの刺し傷があります。これをディレクトリにドロップします。

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 に答える