Rozsah platnosti
Základním je v Ruby místní rozsah platnosti, "globální" rozsah platnosti a třídní rozsah platnosti.
Příklad:
var=2
4.times do |x| puts x=x*var end #=>0,2,4,6
puts x #=>undefined local variable or method `x' for main:Object (NameError)
Tato chyba se objeví protože toto x(toplevel) není x(místní) uvnitř do..end bloku x(místní) je lokální proměnná vzhledem k bloku, zatímco při zkoušení x(toplevel) voláme x proměnnou která je v rozsahu nejvyšší úrovně, a protože tam není, Ruby protestuje.
4.times do |$global| $global=$global*var end #=>0,2,4,6 poslední přiřazení $global je 6
puts $global
toto funguje protože prefixace proměnné se značkou dolaru dělá proměnnou globální, $ není moc dobrý ale zato jednoduchý, doporučuje se nepoužívat nebo užívat šetrně tyto globální proměnné.
4.times do |@instvar| @instvar=@instvar*var end #=>0,2,4,6 poslední přiřazení $global je 6
puts @instvar
@instance_proměnná, instance čeho?? nejvyšší úrovně, která ji efektivně udělá globální $proměnná
class Test
def initialize(arg1='kiwi')
@instvar=arg1
@@classvar=@instvar+' rikal jsem ti to!!'
localvar=@instvar
end
def print_instvar
puts @instvar
end
def print_localvar
puts @@classvar
puts localvar
end
end
class SubTest < Test
def print_classvar
puts @@classvar
end
end
var=Test.new
var.print_instvar #=>"kiwi", funguje protože @instance_var je dostupná uvnitř třídy
var.print_localvar #=>undefined local variable or method `localvar' for #<Test:0x2b36208 @instvar="kiwi"> (NameError).
Toto bude tisknout "kivi rikal jsem ti to!!", pak FAIL! s nedefinovanou lokální proměnnou nebo metodou ' localvar ' pro #
class SubSubTest < Test
def print_classvar
puts @@classvar
end
def modify_classvar
@@classvar='kiwi kiwi dotoho!!'
end
end
newvar=SubTest.new #newvar je vytvořen a má @@classvar se stejnou hodnotou jako var instance od Test!!
newvar.print_classvar #=>kiwi rikal jsem ti to!!
Třídní proměnné mají rozsah platnosti v daní třídě a v potomcích,
tyto proměnné mohou existovat napříč třídami,a mohou být ovlivěny akcemi potomků ;-)
subtest=SubSubTest.new
subtest.print_classvar #Pojďme přidat metodu která změní obsah @@classvar v SubSubTest
subtest.modify_classvar
Toto nové dítě testu má také @@clasvar s originální hodnotou newvar.print_classvar, jeho hodnota @@classvar byla změněná ' kivi kivi dotoho!!' z toho plyne poučení, že @@classvar je "sdílený" napříč mateřskými a dětskými třídami.