Живко обнови решението на 29.10.2012 11:15 (преди около 12 години)
+class Collection
+ include Enumerable
+
+ attr_accessor :songs
+
+ def initialize
+ @songs = []
+ end
+
+ def each(&block)
+ @songs.each &block
+ end
+
+ def names
+ @songs.map(&:name).uniq
+ end
+
+ def artists
+ @songs.map(&:artist).uniq
+ end
+
+ def albums
+ @songs.map(&:album).uniq
+ end
+
+ def self.parse(text)
+ new_collection = Collection.new
+ text.split("\n").select { |line| !line.empty? }.each_slice(3) do |song_data|
+ new_collection.songs << Song.new(song_data)
+ end
+ new_collection
+ end
+
+ def filter(criteria)
+ new_collection = Collection.new
+ new_collection.songs = @songs.select { |song| criteria.is_satisfied.(song) }
+ new_collection
+ end
+
+ def adjoin(other_collection)
+ new_collection = Collection.new
+ new_collection.songs = @songs + other_collection.songs
+ new_collection
+ end
+end
+
+
+class Criteria
+ attr_accessor :is_satisfied
+
+ def create(attribute_name, needle)
+ @is_satisfied = ->(song) { needle == song.send(attribute_name) }
+ self
+ end
+
+ def self.name(name)
+ Criteria.new.create :name, name
+ end
+
+ def self.artist(artist)
+ Criteria.new.create :artist, artist
+ end
+
+ def self.album(album)
+ Criteria.new.create :album, album
+ end
+
+ def &(other)
+ new_criteria = Criteria.new
+ new_criteria.is_satisfied = lambda do |song|
+ @is_satisfied.(song) and other.is_satisfied.(song)
+ end
+ new_criteria
+ end
+
+ def |(other)
+ new_criteria = Criteria.new
+ new_criteria.is_satisfied = lambda do |song|
+ @is_satisfied.(song) or other.is_satisfied.(song)
+ end
+ new_criteria
+ end
+
+ def !
+ new_criteria = Criteria.new
+ new_criteria.is_satisfied = ->(song) { !@is_satisfied.(song) }
+ new_criteria
+ end
+end
+
+
+class Song
+ attr_reader :name, :artist, :album
+
+ def initialize( attributes )
+ @name, @artist, @album = attributes
+ end
+end
new_collection = Collection.new
new_collection.songs = @songs + other_collection.songs
new_collection
Това ме дразни - мога ли някак да избегна въвеждането на променливата new_collection или, като променям songs, да връщам обекта, а не променения му атрибут, т.е. new_collection.songs = ... да връща new_collection, а не new_collection.songs ?
Защо просто не подадеш песните в конструктора на Collection
?