[前][次][番号順一覧][スレッド一覧]

ruby-changes:26827

From: drbrain <ko1@a...>
Date: Sat, 19 Jan 2013 08:48:31 +0900 (JST)
Subject: [ruby-changes:26827] drbrain:r38878 (trunk): * doc/syntax/assignment.rdoc: Added a syntax document on assignment.

drbrain	2013-01-19 08:47:51 +0900 (Sat, 19 Jan 2013)

  New Revision: 38878

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38878

  Log:
    * doc/syntax/assignment.rdoc:  Added a syntax document on assignment.

  Added files:
    trunk/doc/syntax/assignment.rdoc
  Modified files:
    trunk/ChangeLog

Index: doc/syntax/assignment.rdoc
===================================================================
--- doc/syntax/assignment.rdoc	(revision 0)
+++ doc/syntax/assignment.rdoc	(revision 38878)
@@ -0,0 +1,439 @@ https://github.com/ruby/ruby/blob/trunk/doc/syntax/assignment.rdoc#L1
+= 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 {calling methods}[rdoc-ref:syntax/calling_methods.rdoc] 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.
+
+This leads to some potentially 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>.
+
+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 left-hand side:
+
+  a = 1, *[2, 3]
+
+  p a # prints [1, 2, 3]
+
+== Multiple Assignment
+
+You can assign multiple values on the left-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 left hand side than variables on the right 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.
+
+  a, *b = 1, 2, 3
+
+  p a: a, b: b # prints {:a=>1, :b=>[2, 3]}
+
+The <code>*</code> can appear anywhere on the right-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
+
+As with {method arguments}[rdoc-ref:syntax/methods.rdoc] you can decompose an
+Array 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]}
+

Property changes on: doc/syntax/assignment.rdoc
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38877)
+++ ChangeLog	(revision 38878)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jan 19 08:47:33 2013  Eric Hodel  <drbrain@s...>
+
+	* doc/syntax/assignment.rdoc:  Added a syntax document on assignment.
+
 Fri Jan 18 14:11:01 2013  Eric Hodel  <drbrain@s...>
 
 	* doc/syntax/methods.rdoc:  Added Array Decomposition.

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]