DEV Community

Dorthy Thielsen
Dorthy Thielsen

Posted on

Learning Ruby "Advanced" Class Methods

For the last few days I have been learning about "advanced" class methods in Ruby. I am not sure if they are that advanced by a professional's standards but to me they are advanced in comparison. Basically I am learning about class constructors, self, finders, constants, class variables, etc.

The lab I have been working on is to prep me for the big CLI music library final project in Ruby. The assignment is to create class methods to interact with class data regarding creating, finding, and storing song data including the artist name, song name, and the filename. I was given this block of code to begin with.

class Song
  attr_accessor :name, :artist_name
  @@all = []

  def self.all
    @@all
  end

  def save
    self.class.all << self
  end
Enter fullscreen mode Exit fullscreen mode

I was already given my reader and writer methods for song name and artist name. I was also given my empty array that these items would be stored in and a method to save them into the array.

My first task was to create three methods that would instantiate songs using a class method instead of the previously used instance method initialize so I could have more flexibility in my program. I was told to initialize the song, save the song and/or set the name property, and then return the song. For the whole lab, I was also told to try and call on my other class methods so my code wouldn't be repetitive and not abstract.

  def self.create
    song = Song.new #initialize a song
    song.save #save the song using the save method
    song #return the song
  end

  def self.new_by_name(name)
    song = self.new #initialize a song
    song.name=name #set the name to the name property
    song #return the song
  end

  def self.create_by_name(name)
     song = self.create #using the create method from above 
     song.name = name #set the name to the name property
     song #return the song
  end
Enter fullscreen mode Exit fullscreen mode

Also you can see that I have been doing more pseudocode so I am able to code more efficiently and know what steps I need to take. I have removed the rest of my pseudocode in the rest of my code so it is easier to read, but wanted to show that improvement.

Then it was time to build some finder methods. Including one that tripped up me and the technical coaches at Flatiron. For some reason since I had created a blank method later on in the code, it was causing my tests to fail and no one knows why. Anyways, I learned that instead of building complex methods that do multiple things, it is smarter to branch complex methods into smaller chunks. Then you can call on those methods to do larger things in another method, like the self.find_or_create_by_name method below. Which in that method if the song is found in self.find_by_name then return the name if not, self.create the song. In the self.find_by_name method, I wanted to use a finder method on self.all(the array method from above) to find a song and return the song. Then to sort the array alphabetically using the sort_by method. I first wrote the code @@all.sort {|a, b| a <=> b} which also works but I was asked to use the sort_by method.

  def self.find_by_name(name) 
    self.all.find{|song| song.name == name} 
  end

  def self.find_or_create_by_name(name)
     self.find_by_name(name) || self.create_by_name(name) 
   end

  def self.alphabetical
    @@all.sort_by {|song| song.name} 
  end
Enter fullscreen mode Exit fullscreen mode

The next challenge was what to do with a filename string like "Taylor Swift - Blank Space.mp3". I wanted to separate the artist from the song name and get rid of the .mp3. First part was easy. I just need to use the split method and split it at the "-". Getting rid of the .mp3 was something foreign to me. I was looking at everything you can do with enumerables and came across the .gsub method. I highly recommended this article. I used this method to get rid of the pesky .mp3 and substitute in an empty string. Then set the value of the artist name and returned the song.

  def self.new_from_filename(filename)
    artist_name, song_name = filename.split(" - ") 
    song = self.new_by_name(song_name.gsub(".mp3", "")) 
    song.artist_name = artist_name 
    song 
  end

  def self.create_from_filename(filename)
    song = self.new_from_filename(filename) 
    song.save 
    song 
  end
Enter fullscreen mode Exit fullscreen mode

Finally to destroy everything!

  def self.destroy_all
    @@all.clear #can also use @@all = []
  end 
Enter fullscreen mode Exit fullscreen mode

Latest comments (0)