############################### Class ##############################
class Song
def initialize(name, artist, duration)
@name = name
@artist = artist
@duration = duration
end
end
#initialize is a special method in Ruby programs.When you call Song.new to create
#a new Song object, Ruby allocates some memory to hold an uninitialized object and
#then calls that object’s initialize method, passing in any parameters that were passed to new.
#In Ruby, an instance variable is simply a name preceded by an “at” sign (@).
song = Song.new("Bicylops", "Fleck", 260)
puts song.inspect
song1 = Song.new "Bicylops", "Fleck", 260
puts song1.to_s
#In Ruby, classes are never closed: you can always add methods to an existing class.
#We said that Ruby supports to_s for all objects
class Song
def to_s
"Song: #@name--#@artist (#@duration)"
end
end
song = Song.new("Bicylops", "Fleck", 260)
puts song.to_s
################################## Inheritance and Messages #######################
class KaraokeSong < Song
def initialize(name, artist, duration, lyrics)
super(name, artist, duration)
@lyrics = lyrics
end
end
song = KaraokeSong.new("my Way", "Sinatra", 225, "And now, the...")
puts song.to_s
#when Ruby comes across the method invocation song.to_s, it doesn’t actually know
#where to find the method to_s. Instead, it defers the decision until the program is run.
#At that time, it looks at the class of song. If that class implements a method with the
#same name as the message, that method is run. Otherwise, Ruby looks for a method in
#the parent class, and then in the grandparent, and so on up the ancestor chain. If it runs
#out of ancestors without finding the appropriate method, it takes a special action that
#normally results in an error being raised.
class KaraokeSong < Song
def to_s
super + " [#@lyrics]"
end
end
song = KaraokeSong.new("my Way", "Sinatra", 225, "And now, the...")
puts song.to_s
################################# Objects and Attributes ####################
#Ruby offers an interesting and powerful compromise, giving you
#the simplicity of single inheritance and the power of multiple inheritance.
#A Ruby class has only one direct parent, so Ruby is a singleinheritance
#language. However, Ruby classes can include the functionality
#of any number of mixins (a mixin is like a partial class definition).
#This provides a controlled multiple-inheritance-like capability
#with none of the drawbacks.
class Song
def name
@name
end
def artist
@artist
end
def duration
@duration
end
end
song = Song.new("Bicylops", "Fleck", 260)
puts song.artist
puts song.name
puts song.duration
#Because this is such a common idiom, Ruby provides a convenient shortcut:
#attr_reader creates these accessor methods for you.
#In this example, we named the accessor methods name, artist, and
#duration. The corresponding instance variables, @name, @artist, and @duration,
#will be created automatically.
class Song
attr_reader :name, :artist, :duration
end
song = Song.new("Bicylops", "Fleck", 260)
puts song.artist
puts song.name
puts song.duration
################################### Writable Attributes ############################
class Song
def duration=(new_duration)
@duration = new_duration
end
end
song = Song.new("Bicylops", "Fleck", 260)
puts song.duration
song.duration = 257
puts song.duration
#Ruby provides a shortcut for creating these simple attribute-setting methods.
class Song
attr_writer :duration
end
song = Song.new("Bicylops", "Fleck", 260)
song.duration = 257
############################ Virtual Attributes ###########################
class Song
def duration_in_minutes
@duration / 60.0
end
def duration_in_minutes=(new_duration)
@duration = (new_duration * 60)
end
end
song = Song.new("Bicylops", "Fleck", 260)
puts song.duration_in_minutes
song.duration_in_minutes = 4.2
puts song.duration
############################# Class Variables #############################
#A class variable is shared among all objects of a class.
#class variables must be initialized before they are used.
class Song
@@plays = 0
def initialize(name, artist, duration)
@name = name
@artist = artist
@duration = duration
@plays = 0
end
def play
@plays += 1
@@plays += 1
end
end
s1 = Song.new("Song1", "Artist1", 234)
s2 = Song.new("Song2", "Artist2", 345)
s1.play
s2.play
s1.play
s2.play
#Class variables are private to a class and its instances. If you want to make them accessible
#to the outside world, you’ll need to write an accessor method. This method could
#be either an instance method
######################################### Class Methods #####################
class Example
#instance method
def instance_method
end
#class method
def Example.class_method
end
end
class SongList
MAX_TIME = 5 * 60
def SongList.is_too_long(song)
return song.duration > MAX_TIME
end
end
song1 = Song.new("Bicylops", "Fleck", 260)
SongList.is_too_long(song1)
song2 = Song.new("The Calling", "Santana", 468)
SongList.is_too_long(song2)