2012-05-18 3 views
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 오브젝트로 확장됩니다.

다른 방법의 매개 변수로 메서드를 전달하는 방법이 있습니까?

답변

1

당신은 method 문자열 또는 기호가 첫 번째 예에서와 같이, 메소드 이름을 나타내는입니다 Object#send를 사용할 수 있습니다.

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

UPDATE 당신의 "추가 포인트"질문에 대한

및 megas '답변을 따기, 여기에 열거 기반의 접근 방식에 찔린입니다 : 그냥 #recursively이로 변경합니다.

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 } 
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) 
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 
1

내가 여기에 생각이 Enumerable에서에서 each 방법을 전문화해야한다 것 기준 치수. 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.map { |object| object.size } #=> [435435,64545,23434,45645, ...] 

이 추가적으로 예를 크기의 배열을 줄 것이다

@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.each_with_index.map { |object, index| [index, object.size] } 

#=> [ [0,43543], [1,33534], [2,34543564], [3,345435], ...] 
+0

나는 지금까지이 경로의 의미를 정말 좋아한다고 말하고 싶습니다. 'block_given? '은 정확히 무엇을 검사합니까? – webdesserts

+1

블록을 통과하는지 확인하십시오. 업데이트는 – megas

+0

입니다. 제 프로젝트에 큰 도움이 될 것이라고 생각합니다. 노력에 감사드립니다. 나는 궁극적으로 @ Rob Davis의 대답이 초기 질문에 더 잘 대답한다고 생각합니다. 그래서 나는 미래의 방문객들을 확인해 보겠습니다. 내가 너를 더 포기할 수만 있다면 – webdesserts

관련 문제