Ruby Programming/Syntax/Operators

上一項: 字義 索引 下一項: 控制結構

Operators 编辑

1. Assignment 编辑

Assignment in Ruby is done using the equal operator "=". This is both for variables and objects, but since strings, floats, and integers are actually objects in Ruby, you're always assigning objects.

Examples:

 myvar = 'myvar is now this string'
 var = 321
 dbconn = Mysql::new('localhost','root','password')

Self assignment

 x = 1           #=>1
 x += x          #=>2
 x -= x          #=>0
 x =+ 4          #=>x was 0 so x= + 4 # x is positive 4
 x *= x          #=>16
 x **= x         #=>18446744073709551616 #Raise to the power
 x /= x          #=>1

A frequent question from C and C++ types is "How do you increment a variable? Where are ++ and -- operators?" In Ruby, one should use x+=1 and x-=1 to increment or decrement a variable.

 x = 'a'
 x.succ!         #=>"b" : succ! method is defined for String, but not for Integer types

Multiple assignments

Examples:

 var1, var2, var3 = 10, 20, 30
 puts var1           #=>var1 is now 10
 puts var2           #=>var2 is now 20,var3...etc
 
 myArray=%w(John Michel Fran Adolf) # %w() or %{} can be used as syntatic sugar to simplify array creation
 var1,var2,var3,var4=*myArray
 puts var1           #=>John
 puts var4           #=>Adolf
 names,school=myArray,'St. Whatever'
 names               #=>["John", "Michel", "Fran", "Adolf"]
 school              #=>"St. Whatever"

Conditional assignment

 x = find_something() #=>nil
 x ||= "default" #=>"default" : value of x will be replaced with "default", but only if x is nil
 x ||= "other" #=>"default" : value of x is not replaced if it already is other than nil

Operator ||= can be shorthand for code like:

 x = "(some fallback value)" if x.nil?

Scope 编辑

Basically in Ruby there's a local scope,a "global" scope and classes scope.

Example:

 var=2
 1..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)

This error appears because this x(toplevel) is not the x(local) inside the do..end block the x(local) is a local variable to the block, whereas when trying the puts x(toplevel) we're calling a x variable that is in the top level scope, and since there's not one, Ruby protests.

 1..4.times do |arg| $global=arg; puts $global=$global * var end  #=>0,2,4,6 last assignment of $global is 6
 puts $global

#this works because prefixing a variable with a dollar sign makes the variable a global,the $ is ugly and the reason behind this is simply, to make you not to use or use sparingly these global variables

 1..4.times do |arg| @instvar=arg; @instvar=@instvar*var end  #=>0,2,4,6 last assignment of $global is 6
 puts @instvar

#A @instance_variable, instance of what?? of top level, which effectively makes it a global-like $variable

 class Test
   def initialize(arg1='kiwi')
     @instvar=arg1
     @@classvar=@instvar+' told you so!!'
     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", it works because a @instance_var can be accesed inside the class
 var.print_localvar             #=>undefined local variable or method `localvar' for #<Test:0x2b36208 @instvar="kiwi"> (NameError).

This will print "kiwi told you so!!", then FAIL! with a undefined local variable or method `localvar' for #<Test:0x2b36208 @instvar="kiwi"> (NameError). Why? well, in the scope of the method print_localvar there doesn't exists localvar, it exists in method initialize(until GC kicks it out). On the other hand ,class variables '@@classvar' and '@instvar' are in scope across the entire class and int the case of @@class variables,across the children classes

 class SubSubTest < Test
   def print_classvar
     puts @@classvar
   end
   def modify_classvar
     @@classvar='kiwi kiwi waaai!!'
   end
 end
 newvar=SubTest.new              #newvar is created and it has @@classvar with the same value as the var  instance of Test!!
 newvar.print_classvar           #=>kiwi told you so!! 
 Class variables have the scope of parent class AND children,
 these variables are can live across classes,and can be affected by the children actions ;-)
 subtest=SubSubTest.new
 subtest.print_classvar          #lets add a method that modifies the contents of @@classvar in  SubSubTest
 subtest.modify_classvar

This new child of Test also has @@clasvar with the original value newvar.print_classvar he value of @@classvar has been changed to 'kiwi kiwi waaai!!' this shows that @@classvar is "shared" across parent and child classes

上一項: 字義 索引 下一項: 控制結構