Buscar..


Sintaxis

  • $ global_variable
  • @@ class_variable
  • @Instancia variable
  • variable local

Observaciones

Las variables de clase se comparten en la jerarquía de clases. Esto puede resultar en un comportamiento sorprendente.

class A
  @@variable = :x

  def self.variable
    @@variable
  end
end

class B < A
  @@variable = :y
end

A.variable  # :y

Las clases son objetos, por lo que las variables de instancia se pueden usar para proporcionar un estado que sea específico para cada clase.

class A
  @variable = :x

  def self.variable
    @variable
  end
end

class B < A
  @variable = :y
end

A.variable  # :x

Variables locales

Las variables locales (a diferencia de las otras clases de variables) no tienen ningún prefijo

local_variable = "local"
p local_variable
# => local

Su alcance depende de donde se ha declarado, no se puede usar fuera del alcance de "contenedores de declaración". Por ejemplo, si una variable local se declara en un método, solo se puede usar dentro de ese método.

def some_method
    method_scope_var = "hi there"
    p method_scope_var
end

some_method
# hi there
# => hi there

method_scope_var
# NameError: undefined local variable or method `method_scope_var'

Por supuesto, las variables locales no se limitan a los métodos, como regla de oro podría decir que, tan pronto como declare una variable dentro de un bloque do ... end o envuelto entre llaves {} , será local y estará dentro del alcance de El bloque ha sido declarado en.

2.times do |n|
    local_var = n + 1
    p local_var
end
# 1
# 2
# => 2

local_var
# NameError: undefined local variable or method `local_var'

Sin embargo, las variables locales declaradas en if o los bloques de case se pueden usar en el ámbito principal:

if true
    usable = "yay"
end

p usable
# yay
# => "yay"

Si bien las variables locales no pueden utilizarse fuera de su bloque de declaración, se transmitirán a los bloques:

my_variable = "foo"

my_variable.split("").each_with_index do |char, i|
    puts "The character in string '#{my_variable}' at index #{i} is #{char}"
end
# The character in string 'foo' at index 0 is f
# The character in string 'foo' at index 1 is o
# The character in string 'foo' at index 2 is o
# => ["f", "o", "o"]

Pero no a las definiciones de método / clase / módulo

my_variable = "foo"

def some_method
    puts "you can't use the local variable in here, see? #{my_variable}"
end

some_method
# NameError: undefined local variable or method `my_variable'

Las variables utilizadas para los argumentos de bloque son (por supuesto) locales al bloque, pero eclipsarán las variables previamente definidas, sin sobrescribirlas.

overshadowed = "sunlight"

["darkness"].each do |overshadowed|
    p overshadowed
end
# darkness
# => ["darkness"]

p overshadowed
# "sunlight"
# => "sunlight"

Variables de clase

Las variables de clase tienen un amplio alcance de clase, se pueden declarar en cualquier parte de la clase. Una variable se considerará una variable de clase cuando se prefija con @@

class Dinosaur
    @@classification = "Like a Reptile, but like a bird"
    
    def self.classification
        @@classification
    end

    def classification
        @@classification
    end
end

dino = Dinosaur.new
dino.classification
# => "Like a Reptile, but like a bird"
  
Dinosaur.classification
# => "Like a Reptile, but like a bird"

Las variables de clase se comparten entre clases relacionadas y se pueden sobrescribir de una clase secundaria

class TRex < Dinosaur
    @@classification = "Big teeth bird!"
end

TRex.classification
# => "Big teeth bird!"

Dinosaur.classification
# => "Big teeth bird!"

Este comportamiento no es deseado la mayor parte del tiempo y se puede sortear mediante el uso de variables de instancia de nivel de clase.

Las variables de clase definidas dentro de un módulo no sobrescribirán sus variables de clase incluidas las clases:

module SomethingStrange
    @@classification = "Something Strange"
end

class DuckDinosaur < Dinosaur
    include SomethingStrange
end

DuckDinosaur.class_variables
# => [:@@classification]
SomethingStrange.class_variables
# => [:@@classification]

DuckDinosaur.classification
# => "Big teeth bird!"

Variables globales

Las variables globales tienen un alcance global y, por lo tanto, se pueden utilizar en todas partes. Su alcance no depende de donde se definan. Una variable se considerará global, cuando se prefija con un signo $ .

$i_am_global = "omg"

class Dinosaur
    def instance_method
       p "global vars can be used everywhere. See? #{$i_am_global}, #{$another_global_var}" 
    end

    def self.class_method
       $another_global_var = "srsly?"
       p "global vars can be used everywhere. See? #{$i_am_global}"
    end
end

Dinosaur.class_method
# "global vars can be used everywhere. See? omg"
# => "global vars can be used everywhere. See? omg"

dinosaur = Dinosaur.new
dinosaur.instance_method
# "global vars can be used everywhere. See? omg, srsly?"
# => "global vars can be used everywhere. See? omg, srsly?"

Dado que una variable global se puede definir en todas partes y será visible en todas partes, llamar a una variable global "indefinida" devolverá nil en lugar de generar un error.

p $undefined_var
# nil
# => nil

Si bien las variables globales son fáciles de usar, su uso está fuertemente desaconsejado a favor de las constantes.

Variables de instancia

Las variables de instancia tienen un amplio alcance de objeto, se pueden declarar en cualquier parte del objeto, sin embargo, una variable de instancia declarada en el nivel de clase, solo será visible en el objeto de clase. Una variable se considerará una variable de instancia cuando se prefija con @ . Las variables de instancia se utilizan para establecer y obtener atributos de un objeto y devolverán cero si no se definen.

class Dinosaur
    @base_sound = "rawrr"

    def initialize(sound = nil)
        @sound = sound || self.class.base_sound
    end

    def speak
        @sound
    end

    def try_to_speak
        @base_sound
    end

    def count_and_store_sound_length
        @sound.chars.each_with_index do |char, i|
            @sound_length = i + 1
            p "#{char}: #{sound_length}"
        end
    end
    
    def sound_length
        @sound_length
    end

    def self.base_sound
        @base_sound
    end
end

dino_1 = Dinosaur.new
dino_2 = Dinosaur.new "grrr"

Dinosaur.base_sound
# => "rawrr"
dino_2.speak
# => "grrr"

No se puede acceder a la variable de instancia declarada en el nivel de clase en el nivel de objeto:

dino_1.try_to_speak
# => nil

Sin embargo, usamos la variable de instancia @base_sound para crear una instancia del sonido cuando no se pasa ningún sonido al nuevo método:

dino_1.speak
# => "rawwr"

Las variables de instancia se pueden declarar en cualquier parte del objeto, incluso dentro de un bloque:

dino_1.count_and_store_sound_length
# "r: 1"
# "a: 2"
# "w: 3"
# "r: 4"
# "r: 5"
# => ["r", "a", "w", "r", "r"]

dino_1.sound_length
# => 5

Las variables de instancia no se comparten entre instancias de la misma clase

dino_2.sound_length
# => nil

Esto se puede usar para crear variables de nivel de clase, que no serán sobrescritas por una clase hija, ya que las clases también son objetos en Ruby.

class DuckDuckDinosaur < Dinosaur
    @base_sound = "quack quack"
end

duck_dino = DuckDuckDinosaur.new
duck_dino.speak
# => "quack quack"
DuckDuckDinosaur.base_sound
# => "quack quack"
Dinosaur.base_sound
# => "rawrr"


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow