Recherche…


Syntaxe

  • $ global_variable
  • @@ class_variable
  • @instance_variable
  • variable locale

Remarques

Les variables de classe sont partagées dans la hiérarchie des classes. Cela peut entraîner un comportement surprenant.

class A
  @@variable = :x

  def self.variable
    @@variable
  end
end

class B < A
  @@variable = :y
end

A.variable  # :y

Les classes sont des objets, donc les variables d'instance peuvent être utilisées pour fournir un état spécifique à chaque classe.

class A
  @variable = :x

  def self.variable
    @variable
  end
end

class B < A
  @variable = :y
end

A.variable  # :x

Variables locales

Les variables locales (contrairement aux autres classes de variables) n'ont pas de préfixe

local_variable = "local"
p local_variable
# => local

Son étendue dépend de l'endroit où il a été déclaré, il ne peut pas être utilisé en dehors du périmètre "déclaration conteneurs". Par exemple, si une variable locale est déclarée dans une méthode, elle ne peut être utilisée que dans cette méthode.

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'

Bien sûr, les variables locales ne se limitent pas aux méthodes, en règle générale , vous pouvez dire que, dès que vous déclarez une variable à l' intérieur d' un do ... end bloc ou wrapped accolades {} , il sera local et à SCOPED le bloc dans lequel il a été déclaré

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'

Cependant, les variables locales déclarées dans if ou les blocs de case peuvent être utilisés dans la parent-scope:

if true
    usable = "yay"
end

p usable
# yay
# => "yay"

Bien que les variables locales ne puissent pas être utilisées en dehors de son bloc de déclaration, elles seront transmises à des blocs:

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"]

Mais pas aux définitions de méthode / classe / module

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'

Les variables utilisées pour les arguments de bloc sont (naturellement) locales au bloc, mais occulteront les variables précédemment définies, sans les écraser.

overshadowed = "sunlight"

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

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

Variables de classe

Les variables de classe ont une portée étendue, elles peuvent être déclarées n'importe où dans la classe. Une variable sera considérée comme une variable de classe avec le préfixe @@

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"

Les variables de classe sont partagées entre les classes associées et peuvent être écrasées à partir d'une classe enfant

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

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

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

Ce comportement est indésirable la plupart du temps et peut être contourné en utilisant des variables d'instance de niveau classe.

Les variables de classe définies dans un module n'écrasent pas leurs variables de classe incluant les classes:

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

Les variables globales ont une portée mondiale et peuvent donc être utilisées partout. Leur portée ne dépend pas de l'endroit où ils sont définis. Une variable sera considérée comme globale lorsqu'elle est préfixée par un signe $ .

$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?"

Comme une variable globale peut être définie partout et sera visible partout, l'appel d'une variable globale "non définie" renverra zéro au lieu de générer une erreur.

p $undefined_var
# nil
# => nil

Bien que les variables globales soient faciles à utiliser, leur utilisation est fortement déconseillée en faveur des constantes.

Variables d'instance

Les variables d'instance ont une portée étendue à l'objet, elles peuvent être déclarées n'importe où dans l'objet, cependant une variable d'instance déclarée au niveau de la classe ne sera visible que dans l'objet de classe. Une variable sera considérée comme une variable d'instance avec le préfixe @ . Les variables d’instance permettent de définir et d’obtenir des attributs d’objet et renvoient zéro si elles ne sont pas définies.

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"

La variable d'instance déclarée au niveau de la classe n'est pas accessible au niveau de l'objet:

dino_1.try_to_speak
# => nil

Cependant, nous avons utilisé la variable d’instance @base_sound pour instancier le son quand aucun son n’est transmis à la nouvelle méthode:

dino_1.speak
# => "rawwr"

Les variables d'instance peuvent être déclarées n'importe où dans l'objet, même à l'intérieur d'un bloc:

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

Les variables d'instance ne sont pas partagées entre les instances de la même classe

dino_2.sound_length
# => nil

Cela peut être utilisé pour créer des variables de niveau classe, qui ne seront pas écrasées par une classe enfant, car les classes sont également des objets dans 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow