Analysis of Ruby relay and message-related knowledge, analysis of ruby

Source: Internet
Author: User

Analysis of Ruby relay and message-related knowledge, analysis of ruby

Inheritance allows you to create a class as the refinement and specialization of another class ). For example, in our automatic karaoke system, the concept of "Song" is encapsulated in the Song category. Then, as the market grows, we need to provide karaoke support. A karaoke song is no different from other songs (it just does not have a sound track for the lead singer, so we don't have to worry about it ). However, it also includes a set of lyrics and time information. When our automatic karaoke player is playing a karaoke song, the lyrics should scroll along with the music on the screen before the karaoke player.

One way to solve this problem is to define a new class KaraokeSong, that is, adding the Song lyrics.

class KaraokeSong <Song  def initialize(name,artist,duration,lyrics)    super(name,artist,duration)    @lyrics = lyrics  endend

The "<Song" in the class definition line tells Ruby that KaraokeSong is a subclass of Song (subclass). Therefore, this also means that Song is the superclass of KaraokeSong)

song = KaraokeSong.new("My Way","Sinatra",255,"And now,the ...")song.to_s        ->          *Song:My Way--Sinatra(225)*

No lyrics are displayed when the to_s method is called.

This is related to the Mechanism in which Ruby determines which method to call when we send a message to an object. During the initial parsing (parse) of the program code, when Ruby encounters a method call song. in to_s, it does not know where to find the to_s method, but delays the determination until the program starts running. At that time, Ruby looked at the class to which the song belongs. If this class implements the same method as the message name, run this method. Otherwise, Ruby will view the methods in its parent class, and then the grandfather class, where the entire ancestor chain is traced back. In the end, if it does not find a proper method in the ancestor class, Ruby will produce a special behavior, which usually leads to an error.

Let's solve this problem by implementing KaraokeSong # to_s. You have many ways to complete it. Let's start with the method of the most slot. We copy the to_s method from the Song class and add the lyrics information.

class KaraokeSong #... def to_s   "KS: #@name--#@artist(#@duration){#@lyrics}"  endendsong = KaraokeSong.new("My Way", "Sinatra", 225,"And now,the...")song.to_s     ->"KS: My Way--Sinatra(225){And now,the...}"

The value of the instance variable @ lyrics is correctly displayed. However, in this way, the subclass needs to directly access the instance variables of its ancestor. So why is this a bad way to implement to_s?

The answer is related to a good programming style (sometimes called decoupling ). Directly stamp it into the internal structure of the parent class, and check its instance variables explicitly, so that we are closely bound with the implementation of the parent class.

We solve this problem by letting each class handle its own implementation details. When KaraokeSong # to_s is called, we call the to_s method of the parent class to obtain the details of the song. Then, add the lyrics and return the results. The technique used here is the Ruby keyword super. When you call super without parameters, Ruby sends a message to the parent class of the current object, requiring it to call the method with the same name in the subclass. Ruby passes the parameters we used to call the method to the method of the parent class. Now, we can implement the improved to_s method.

class KaraokeSong <Song  #Format ourselves as a string by appending  #our lyrics to our parent's to_s value.  def to_s    super+"{#@lyrics}"  endendsong = KaraokeSong.new("My Way", "Sinatra" ,225, "And now,the...")song.to_s      ->"Song:My Way--Sinatra(225){And now,the...}"

We clearly tell Ruby that KaraokeSong is a subclass of Song, but we do not specify the parent class of the Song class. If you do not specify the parent class when defining a class, Ruby uses the Object class as its parent class by default. This means that the ancestor of all classes is an Object, and the Object instance method is available to all objects in Ruby.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.