2014-03-01 45 views
1

鑑於提取祖先高達「我」

class Bird 
    def self.bird_ancestors 
    ancestors.first(ancestors.find_index(Bird)+1) 
    end 
end 

class Duck < Bird 
end 

class FeatheredDuck < Duck 
end 

FeatheredDuck.bird_ancestors => [FeatheredDuck,Duck,Bird] 
Duck.bird_ancestors => [Duck,Bird] 
Bird.bird_ancestors => [Bird] 

如何可以引用內BirdBird無需它是明確的?我知道self__class__ doesnt的工作。

+3

您的類定義的排序是錯誤的。 – Agis

+2

另外,你的意思是「'self'不起作用」?在類方法中,'self'指向當前類。 – Agis

+0

另外,你似乎在呈現如此多與你的問題無關的事情。 – sawa

回答

1

這將做到這一點:

class Bird 
    def self.bird_ancestors 
    ancestors.take_while { |c| c.respond_to? __method__ } 
    end 
end 

class Duck < Bird 
end 

class FeatheredDuck < Duck 
end 

FeatheredDuck.bird_ancestors #=> [FeatheredDuck, Duck, Bird] 
Duck.bird_ancestors   #=> [Duck, Bird] 
Bird.bird_ancestors   #=> [Bird] 

select也有效,但take_while(由@Aditya建議)更好,因爲它停止搜索ancestors一旦false從塊中返回。

+1

爲什麼在我們知道方法名稱時使用'__method__'?我的意思是它是靜態的。 –

+0

@SachinSingh,只有一個原因和一個原因:如果將來方法的名稱被改變,那麼不必記住改變方法的主體。 (儘管問題很好。) –

2

裏面一個類的方法,self指當前類對象:

class Bird 
    def self.foo 
    self 
    end 
end 

p Bird.foo # => "Bird" 
+1

這不行。提問者希望通過Bird提取祖先。 –

+0

@agis你是對的,但是對於'Duck.foo'和'FeatheredDuck.foo',它會解析爲Duck和FeatheredDuck而不是Bird這是他想要的。 –

0

你可以做這樣的事情:

class Bird 
    def self.bird_ancestors 
     class_name = method(__method__).owner.to_s.gsub(/#<Class:|>/,'') 
     ancestors.first(ancestors.map{|x| x.to_s}.find_index(class_name)+1) 
    end 
end 

(__method__ is the current method)