2014-10-03 67 views
0

我有兩個類:一個用於創建歌曲,另一個用於製作播放列表,播放列表播放歌曲。使用參數訪問類

class Song 
    attr_accessor :title , :artist 
    def initialize(title, artist) 
    @title = title 
    @artist = artist 
    end 
end 

class Playlist 
    def initialize(*songs) 
    @playlist = [] 
    songs.each{|key| 
     add(key) 
    } 
    end 
    def add(*songs) 
    songs.each {|key| 
     @playlist << key 
    } 
    end 
end 

我創作歌曲:

anna_sun = Song.new("Anna Sun", "Walk The Moon") 
girls = Song.new("Girls", "The 1975") 

然後添加這些歌曲到一個新的Playlist

alternative = Playlist.new(anna_sun, girls) 

我想創建一個名爲sort_byPlaylist類裏面的方法。我想sort_by採取一個參數,告訴通過什麼來排序播放列表。這是我想出的

class Playlist 
    def sort_by(type) 
    @playlist.sort_by! {|item| 
     item.type 
    } 
    end 
end 

但是,這不起作用的原因有兩個。其中一個,我試圖稱之爲

alternative.sort_by(artist) 

它說artist沒有定義。還有兩個,它說type是一個未定義的方法。我想知道是否有辦法得到我想要的結果。

回答

2

下面應該工作:

class Playlist 

    def sort_by(type) 
    @playlist.sort_by! {|item| 
    item.public_send type 
    } 
    end 

end 

代替item.public_send typeitem.send type,你也可以使用形式eval所有的罪惡,他們意味着:

  • eval "item.#{type}"
  • item.instance_eval type.to_s

如果我是你,我會簡單地將sort_by的電話委託給Playlist@playlist,這將給我提供來自Enumerable mixin的原始#sort_by的所有靈活性。

def sort_by!(*args,&blk) 
    @playlist.sort_by! *args, &blk 
end 

委派多個方法,考慮forwardablehttp://www.ruby-doc.org/stdlib-1.9.3/libdoc/forwardable/rdoc/Forwardable.html)。

1

您可以定義

class Playlist 
    def sort_by(type); @playlist.sort_by!(&type) end 
end 

,並通過符號

alternative.sort_by(:artist) 

的方式,Playlist方法是非常低效的。他們應該是

class Playlist 
    def initialize(*songs); @playlist = songs end 
    def add(*songs); @playlist.concat(songs) end 
end