Metaprogramming with ruby, methods with SELF

Asked

Viewed 345 times

1

good evening... I come from other languages somewhat different to Ruby, such as C/C++ , JAVA... And I got a little lost trying to understand the difference between the following methods:

Class teste 
     def novo
       "1"
     end
     def self.testenovo
     "2"
     end
end

I would like to know the difference between the two methods... I have been researching and saw that self is a class method and the "new" is an instance method... this applies where ? at execution time just right ? because by doing so and declaring an instantiated variable of the test class, it will have both methods, correct? then where does this kind of statement apply ? Thank you!

  • Hello Rafael! I saw that you put "metaprogramming" in your question, and my answer ended up not talking about it - it answers the questions you put into the body of the question. Perhaps it is interesting for you to ask a new question, i.e. "What is the usefulness of the self in metaprogramming?" or something like that - can bring more interesting answers! Oh, and welcome to Stack Overflow! :)

1 answer

0


Let’s say you’re writing a show about cars, and knowing that we’re in 2017, only two years before the cars fly.

Your show would look something like this:

class Carro
  @@voa = false # carros não podem voar ainda

  def self.voa(v) # nosso setter pra quando carros puderem voar
    @@voa = v
  end

  def initialize(marca)
    @marca = marca
  end

  def explica
    if @@voa
      print 'eu sou um ' + @marca.to_s + ' e eu posso voar!'
    else
      print 'eu sou um ' + @marca.to_s + ' e eu nao posso voar ainda! :('
    end
  end
end

def self.voa(v), allows us to modify the variable @@voa, which is a variable of classe, then applies to all instances.

Let’s create some cars:

carros = []
carros << Carro.new('chevrolet')
carros << Carro.new('ford')
carros << Carro.new('volkswagen')
carros << Carro.new('fiat')

And we call the method explica of each of them:

carros.each { |c| puts c.explica }

Exit:

eu sou um chevrolet e eu nao posso voar ainda! :(
eu sou um ford e eu nao posso voar ainda! :(
eu sou um volkswagen e eu nao posso voar ainda! :(

Now when we get to 2019, we can just call:

Carro.voa(true) # chama pela classe!

All our cars become spinners, Uhul!

eu sou um chevrolet e eu posso voar!
eu sou um ford e eu posso voar!
eu sou um volkswagen e eu posso voar!
eu sou um fiat e eu posso voar!

See working on repl it..

A Better Example

How are we talking about a método de classe, it is possible to use it to store all instances created in the class itself:

class Pessoa
  # variável de classe, onde guardaremos nossas instâncias
  @@pessoas = Array.new
  attr_accessor :nome

  def self.lista_pessoas
    @@pessoas
  end

  def initialize(nome)
    @nome = nome
    # ao instanciar, já guardamos no array
    @@pessoas << self
  end
end

# criando algumas pessoas
pessoa_1 = Pessoa.new('Ana')
pessoa_2 = Pessoa.new('Julia')
pessoa_3 = Pessoa.new('Tatiana')

# e listando todas, à partir do método de classe
Pessoa.lista_pessoas.each { |p| puts p.nome }

See working on repl it..

Example taken from here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.