What practical applicability of the word super in Ruby?

6

There are several explanations on the internet about it. But I still can not understand what the practical applicability of the word super in ruby is. Okay, I know it's for calling the same-named method in the superclass. Right. But why would I want to do that? I have less than a year of work in the area, so I have not yet seen that word being used in practice. Could someone give an example or something?

    
asked by anonymous 17.12.2014 / 17:20

2 answers

5

There are many situations where you need to extend certain functionality of an existing class. There may be several specializations for a particular behavior.

Of course, this can be done by simply changing the original class, perhaps by setting if to each new situation that arises.

But this is not good practice from a modeling point of view. The code is getting confusing and the chance of new errors appearing is great.

In an ideal class model you would never need to change an existing class to add new functionality or more specific behavior. It would suffice to extend a class.

Although there are several practical examples, not all of them work out of context. I'll work with some below.

Practical constructor example

Suppose you have class Pessoa :

class Pessoa
    def initialize(nome)  
        @nome = validarNome(nome)
    end
    def validarNome(nome)
        ...
    end
end

And now a specialization PessoaFisica :

class PessoaFisica < Pessoa
    def initialize(nome, cpf)  
        super(nome)
        @cpf = validarCpf(cpf)
    end
    def validarCpf(cpf)
        ...
    end
end

And one more level of expertise Funcionario :

class Funcionario < PessoaFisica
    def initialize(nome, cpf, pis)  
        super(nome, cpf)
        @pis = validarPis(pis)
    end
    def validarPis(pis)
        ...
    end
end

In the examples above, the superclass constructor takes care of the validation of the attribute it has.

Subclasses add new attributes and invoke the constructor of their superclass by delegating the initialization and validation of inherited attributes.

This is a way to maintain existing functionality, add new features and ensure the correct behavior of the program by reusing what already exists, without duplicating code.

Example of a "decorative" method

Imagine that you have a class that returns a message:

class GeradorMensagem
    def getMensagem
        "Olá mundo!"
    end
end

Now you need to create a specialization of this message for display on a web page. It could do something like:

class GeradorMensagemHtml < GeradorMensagem
    def getMensagem
        "<div>" + super + "</div>"
    end
end

Example of specialized behavior

Given a class Cliente like this:

class Cliente
    def limiteCredito
      #consulta limite de crédito
    end
end

There may be ClienteEspecial which, in addition to the normal limit, has a special value. The limit would then be the sum of both. Let's see how this can be implemented with reuse:

class ClienteEspecial < Cliente
    def limiteCreditoEspecial
        #consulta limite de crédito especial
    end
    def saldo
        limiteCredito + limiteCreditoEspecial
    end
end
    
17.12.2014 / 17:44
2

Resetting, overwriting, and super

  • Resetting Methods

Resetting a method involves replacing one method with another. And the original method simply gets lost.

Example:

class Rectangle
  def initialize(length, breadth)
    @length = length
    @breadth = breadth
  end

  def perimeter
    2 * (@length + @breadth)
  end

  def area
    @length * @breadth
  end
end

When invoked area and perimeter methods, we will have 20 and 18 respectively

But if we break the Rectangle class by defining these same methods but without implementing them:

class Rectangle
  def perimeter
  end

  def area
  end
end

The tests fail.

And because almost all Ruby methods can be redefined, special care should be taken especially with base classes like Object, Array and etc. since an unthinking redefinition can break the entire Application, so as a general rule: / p>

  

Never redefine methods, especially if they are defined by language. Even!

  • Overriding Methods

Overwrite in the context of a class is to define a method in a subclass that already exists in the superclass, without affecting its original implementation.

Example:

class MyArray < Array 
  def map
    'in soviet russia...'
  end
end

In the example above we created a subclass MyArray , derived from Array , and we override the Array.map () .

When testing this code, with both objects, we will see that only the behavior of MyArray.map is impaired, leaving the original intact and fully functional.

  • Super Powered

The most common use of inheritance is to override methods of a class so that it does something more than its counterpart in the superclass, instead of overwriting it completely to do something completely different (as in the examples above)

This allows us to reuse behavior that already exists in the superclass and then modify it to suit the needs of the subclass.

Most Object-Oriented languages provide a means of an overriding method to invoke the method instead. In Ruby this happens through the keyword super .

Using super method will invoke its counterpart with the same name, but from the context of the superclass.

Example:

class Animal
  def move
    "I can move"
  end
end

class Bird < Animal
  def move
    super + " by flying"
  end
end

puts Animal.new.move
puts Bird.new.move

In the example above we define the behavior of an Animal class that describes how it moves. A bird is also an animal and by deriving the class Bird from Animal we say that all birds also move.

But birds move in a different way by flying, so we change the Bird.move behavior by invoking move in the context of the superclass, thereby complementing the which birds fly by.

Source: RubyMonk

    
17.12.2014 / 18:08