Question

I want to refactor this:

class Collection
  def artists
    @songs.map { |song| song.artist }.uniq
  end
  def albums
    @songs.map { |song| song.album }.uniq
  end
  def names
    @songs.map { |song| song.name }.uniq
  end
end

into something like this:

class Collection
  song_attributes = [:artist, :album, :name]
  song_attributes.each do |song_attribute|
    define_method song_attribute do
      @songs.map { |song| song.public_send(song_attribute) }.uniq
    end
  end
end

The problem is in line define_method song_attribute do where song_attribute must be pluralized. How do I do this?

I came up only with this, but I suppose there is a better way:

song_attributes = [[:artists, :artist], [:albums, :album], [:names, :name]]
song_attributes.each do |song_attribute|
  define_method song_attribute[0] do
    @songs.map { |song| song.public_send(song_attribute[1]) }.uniq
  end
end
Was it helpful?

Solution

Pass the string in define_method

.....
song_attributes = [:artist, :album, :name]

song_attributes.each do |song_attribute|
  define_method("#{song_attribute}s") do
    @songs.map { |song| song.public_send(song_attribute) }.uniq
  end
end
.....
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top