Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 有没有办法将方法传递给同一对象的方法?_Ruby_Methods - Fatal编程技术网

Ruby 有没有办法将方法传递给同一对象的方法?

Ruby 有没有办法将方法传递给同一对象的方法?,ruby,methods,Ruby,Methods,以下是我想做的: 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

以下是我想做的:

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
为了更好地理解这一点,我正在创建一个小脚本,它将对目录及其所有子目录中的文件进行更改。这些子目录将被扩展为
目录
对象


那么,有没有一种方法可以将一个方法作为另一个方法的参数传递?

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

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)

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

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)
您可以使用,其中
method
是表示方法名称的字符串或符号,如第一个示例所示。只需将您的
#递归更改为:

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

对于你的“额外分数”问题,以及megas的答案,这里有一个基于枚举数的方法。将其放入您的目录:

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 }
您可以使用,其中
method
是表示方法名称的字符串或符号,如第一个示例所示。只需将您的
#递归更改为:

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

对于你的“额外分数”问题,以及megas的答案,这里有一个基于枚举数的方法。将其放入您的目录:

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 }
是的,你能做到-

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
是的,你能做到-

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

我认为这里应该专门介绍可枚举模块中的每个
方法。当您实现
每个
方法时,可枚举模块将提供许多方便的方法,如
映射、删除

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], ...]

我认为这里应该专门介绍可枚举模块中的每个
方法。当您实现
每个
方法时,可枚举模块将提供许多方便的方法,如
映射、删除

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], ...]

我想说,到目前为止,我非常喜欢这条路线的语义。
block\u到底给出了什么?
检查?我认为这对我的项目将是一个巨大的帮助,我感谢你的努力。我确实认为,最终,Rob Davis的答案为最初的问题提供了更好的答案。所以我会查一下他未来的访客。如果我能给你更高的票数,我会的。我也喜欢枚举器的想法,尽管最好不要在开始时将整棵树聚集到@objects中。想象一下,如果您尝试这种方法来搜索文件系统。您不会想要一个包含所有计算机目录的数组。请参阅我的答案,以获得一种更简洁的方法,首先枚举树的深度。我想说,到目前为止,我非常喜欢这条路线的语义。
block\u到底给出了什么?
检查?我认为这对我的项目将是一个巨大的帮助,我感谢你的努力。我确实认为,最终,Rob Davis的答案为最初的问题提供了更好的答案。所以我会查一下他未来的访客。如果我能给你更高的票数,我会的。我也喜欢枚举器的想法,尽管最好不要在开始时将整棵树聚集到@objects中。想象一下,如果您尝试这种方法来搜索文件系统。您不会想要一个包含所有计算机目录的数组。请参阅我的答案,以获得一种更简洁的方法,首先枚举树的深度。