diff options
Diffstat (limited to 'ruby_2_2/doc/syntax/assignment.rdoc')
-rw-r--r-- | ruby_2_2/doc/syntax/assignment.rdoc | 455 |
1 files changed, 0 insertions, 455 deletions
diff --git a/ruby_2_2/doc/syntax/assignment.rdoc b/ruby_2_2/doc/syntax/assignment.rdoc deleted file mode 100644 index adfe6485a4..0000000000 --- a/ruby_2_2/doc/syntax/assignment.rdoc +++ /dev/null @@ -1,455 +0,0 @@ -= Assignment - -In Ruby assignment uses the <code>=</code> (equals sign) character. This -example assigns the number five to the local variable +v+: - - v = 5 - -Assignment creates a local variable if the variable was not previously -referenced. - -== Local Variable Names - -A local variable name must start with a lowercase US-ASCII letter or a -character with the eight bit set. Typically local variables are US-ASCII -compatible since the keys to type them exist on all keyboards. - -(Ruby programs must be written in a US-ASCII-compatible character set. In -such character sets if the eight bit is set it indicates an extended -character. Ruby allows local variables to contain such characters.) - -A local variable name may contain letters, numbers, an <code>_</code> -(underscore or low line) or a character with the eighth bit set. - -== Local Variable Scope - -Once a local variable name has been assigned-to all uses of the name for the -rest of the scope are considered local variables. - -Here is an example: - - 1.times do - a = 1 - puts "local variables in the block: #{local_variables.join ", "}" - end - - puts "no local variables outside the block" if local_variables.empty? - -This prints: - - local variables in the block: a - no local variables outside the block - -Since the block creates a new scope, any local variables created inside it do -not leak to the surrounding scope. - -Variables defined in an outer scope appear inner scope: - - a = 0 - - 1.times do - puts "local variables: #{local_variables.join ", "}" - end - -This prints: - - local variables: a - -You may isolate variables in a block from the outer scope by listing them -following a <code>;</code> in the block's arguments. See the documentation -for block local variables in the {calling -methods}[rdoc-ref:syntax/calling_methods.rdoc] documentation for an example. - -See also Kernel#local_variables, but note that a +for+ loop does not create a -new scope like a block does. - -== Local Variables and Methods - -In Ruby local variable names and method names are nearly identical. If you -have not assigned to one of these ambiguous names ruby will assume you wish to -call a method. Once you have assigned to the name ruby will assume you wish -to reference a local variable. - -The local variable is created when the parser encounters the assignment, not -when the assignment occurs: - - a = 0 if false # does not assign to a - - p local_variables # prints [:a] - - p a # prints nil - -The similarity between method and local variable names can lead to confusing -code, for example: - - def big_calculation - 42 # pretend this takes a long time - end - - big_calculation = big_calculation() - -Now any reference to +big_calculation+ is considered a local variable and will -be cached. To call the method, use <code>self.big_calculation</code>. - -You can force a method call by using empty argument parentheses as shown above -or by using an explicit receiver like <code>self.</code>. Using an explicit -receiver may raise a NameError if the method's visibility is not public. - -Another commonly confusing case is when using a modifier +if+: - - p a if a = 0.zero? - -Rather than printing "true" you receive a NameError, "undefined local variable -or method `a'". Since ruby parses the bare +a+ left of the +if+ first and has -not yet seen an assignment to +a+ it assumes you wish to call a method. Ruby -then sees the assignment to +a+ and will assume you are referencing a local -method. - -The confusion comes from the out-of-order execution of the expression. First -the local variable is assigned-to then you attempt to call a nonexistent -method. - -== Instance Variables - -Instance variables are shared across all methods for the same object. - -An instance variable must start with a <code>@</code> ("at" sign or -commercial at). Otherwise instance variable names follow the rules as local -variable names. Since the instance variable starts with an <code>@</code> the -second character may be an upper-case letter. - -Here is an example of instance variable usage: - - class C - def initialize(value) - @instance_variable = value - end - - def value - @instance_variable - end - end - - object1 = C.new "some value" - object2 = C.new "other value" - - p object1.value # prints "some value" - p object2.value # prints "other value" - -An uninitialized instance variable has a value of +nil+. If you run Ruby with -warnings enabled you will get a warning when accessing an uninitialized -instance variable. - -The +value+ method has access to the value set by the +initialize+ method, but -only for the same object. - -== Class Variables - -Class variables are shared between a class, its subclasses and its instances. - -A class variable must start with a <code>@@</code> (two "at" signs). The rest -of the name follows the same rules as instance variables. - -Here is an example: - - class A - @@class_variable = 0 - - def value - @@class_variable - end - - def update - @@class_variable = @@class_variable + 1 - end - end - - class B < A - def update - @@class_variable = @@class_variable + 2 - end - end - - a = A.new - b = B.new - - puts "A value: #{a.value}" - puts "B value: #{b.value}" - -This prints: - - A value: 0 - B value: 0 - -Continuing with the same example, we can update using objects from either -class and the value is shared: - - puts "update A" - a.update - - puts "A value: #{a.value}" - puts "B value: #{b.value}" - - puts "update B" - b.update - - puts "A value: #{a.value}" - puts "B value: #{b.value}" - - puts "update A" - a.update - - puts "A value: #{a.value}" - puts "B value: #{b.value}" - -This prints: - - update A - A value: 1 - B value: 1 - update B - A value: 3 - B value: 3 - update A - A value: 4 - B value: 4 - -Accessing an uninitialized class variable will raise a NameError exception. - -Note that classes have instance variables because classes are objects, so -try not to confuse class and instance variables. - -== Global Variables - -Global variables are accessible everywhere. - -Global variables start with a <code>$</code> (dollar sign). The rest of the -name follows the same rules as instance variables. - -Here is an example: - - $global = 0 - - class C - puts "in a class: #{$global}" - - def my_method - puts "in a method: #{$global}" - - $global = $global + 1 - $other_global = 3 - end - end - - C.new.my_method - - puts "at top-level, $global: #{$global}, $other_global: #{$other_global}" - -This prints: - - in a class: 0 - in a method: 0 - at top-level, $global: 1, $other_global: 3 - -An uninitialized global variable has a value of +nil+. - -Ruby has some special globals that behave differently depending on context -such as the regular expression match variables or that have a side-effect when -assigned to. See the {global variables documentation}[rdoc-ref:globals.rdoc] -for details. - -== Assignment Methods - -You can define methods that will behave like assignment, for example: - - class C - def value=(value) - @value = value - end - end - - c = C.new - c.value = 42 - -Using assignment methods allows your programs to look nicer. When assigning -to an instance variable most people use Module#attr_accessor: - - class C - attr_accessor :value - end - -When using method assignment you must always have a receiver. If you do not -have a receiver Ruby assumes you are assigning to a local variable: - - class C - attr_accessor :value - - def my_method - value = 42 - - puts "local_variables: #{local_variables.join ", "}" - puts "@value: #{@value.inspect}" - end - end - - C.new.my_method - -This prints: - - local_variables: value - @value: nil - -To use the assignment method you must set the receiver: - - class C - attr_accessor :value - - def my_method - self.value = 42 - - puts "local_variables: #{local_variables.join ", "}" - puts "@value: #{@value.inspect}" - end - end - - C.new.my_method - -This prints: - - local_variables: - @value: 42 - -== Abbreviated Assignment - -You can mix several of the operators and assignment. To add 1 to an object -you can write: - - a = 1 - - a += 2 - - p a # prints 3 - -This is equivalent to: - - a = 1 - - a = a + 2 - - p a # prints 3 - -You can use the following operators this way: <code>+</code>, <code>-</code>, -<code>*</code>, <code>/</code>, <code>%</code>, <code>**</code>, -<code>&</code>, <code>|</code>, <code>^</code>, <code><<</code>, -<code>>></code> - -There are also <code>||=</code> and <code>&&=</code>. The former makes an -assignment if the value was +nil+ or +false+ while the latter makes an -assignment if the value was not +nil+ or +false+. - -Here is an example: - - a ||= 0 - a &&= 1 - - p a # prints 1 - -Note that these two operators behave more like <code>a || a = 0</code> than -<code>a = a || 0</code>. - -== Implicit Array Assignment - -You can implicitly create an array by listing multiple values when assigning: - - a = 1, 2, 3 - - p a # prints [1, 2, 3] - -This implicitly creates an Array. - -You can use <code>*</code> or the "splat" operator or unpack an Array when -assigning. This is similar to multiple assignment: - - a = *[1, 2, 3] - - p a # prints [1, 2, 3] - -You can splat anywhere in the right-hand side of the assignment: - - a = 1, *[2, 3] - - p a # prints [1, 2, 3] - -== Multiple Assignment - -You can assign multiple values on the right-hand side to multiple variables: - - a, b = 1, 2 - - p a: a, b: b # prints {:a=>1, :b=>2} - -In the following sections any place "variable" is used an assignment method, -instance, class or global will also work: - - def value=(value) - p assigned: value - end - - self.value, $global = 1, 2 # prints {:assigned=>1} - - p $global # prints 2 - -You can use multiple assignment to swap two values in-place: - - old_value = 1 - - new_value, old_value = old_value, 2 - - p new_value: new_value, old_value: old_value - # prints {:new_value=>1, :old_value=>2} - -If you have more values on the right hand side of the assignment than variables -on the left hand side the extra values are ignored: - - a, b = 1, 2, 3 - - p a: a, b: b # prints {:a=>1, :b=>2} - -You can use <code>*</code> to gather extra values on the right-hand side of -the assignment. - - a, *b = 1, 2, 3 - - p a: a, b: b # prints {:a=>1, :b=>[2, 3]} - -The <code>*</code> can appear anywhere on the left-hand side: - - *a, b = 1, 2, 3 - - p a: a, b: b # prints {:a=>[1, 2], :b=>3} - -But you may only use one <code>*</code> in an assignment. - -== Array Decomposition - -Like Array decomposition in {method arguments}[rdoc-ref:syntax/methods.rdoc] -you can decompose an Array during assignment using parenthesis: - - (a, b) = [1, 2] - - p a: a, b: b # prints {:a=>1, :b=>2} - -You can decompose an Array as part of a larger multiple assignment: - - a, (b, c) = 1, [2, 3] - - p a: a, b: b, c: c # prints {:a=>1, :b=>2, :c=>3} - -Since each decomposition is considered its own multiple assignment you can use -<code>*</code> to gather arguments in the decomposition: - - a, (b, *c), *d = 1, [2, 3, 4], 5, 6 - - p a: a, b: b, c: c, d: d - # prints {:a=>1, :b=>2, :c=>[3, 4], :d=>[5, 6]} - |