Khi bạn lần đầu nhìn vào mã Ruby, nó có thể sẽ gợi nhớ đến
các ngôn ngữ lập trình mà bạn đã từng sử dụng. Điều này là có chủ đích.
Phần lớn cú pháp quen thuộc với người dùng Perl, Python, và Java
(cùng nhiều ngôn ngữ khác), vì vậy nếu bạn đã từng sử dụng chúng,
việc học Ruby sẽ rất dễ dàng.
{: .summary}

Tài liệu này bao gồm hai phần chính. Phần đầu tiên cố gắng tóm tắt
nhanh những gì bạn có thể mong đợi khi chuyển từ ngôn ngữ *X* sang Ruby.
Phần thứ hai đề cập đến các tính năng chính của ngôn ngữ và so sánh
chúng với những gì bạn đã quen thuộc.

## Điều gì sẽ xảy ra: Từ *ngôn ngữ X* đến Ruby

* [Đến với Ruby từ C và C++](to-ruby-from-c-and-cpp/)
* [Đến với Ruby từ Java](to-ruby-from-java/)
* [Đến với Ruby từ Perl](to-ruby-from-perl/)
* [Đến với Ruby từ PHP](to-ruby-from-php/)
* [Đến với Ruby từ Python](to-ruby-from-python/)

## Các tính năng quan trọng của ngôn ngữ và một số điều cần lưu ý

Dưới đây là một số gợi ý và chỉ dẫn về các tính năng chính của Ruby mà
bạn sẽ gặp khi học Ruby.

### Vòng lặp

Hai tính năng của Ruby hơi khác so với những gì bạn có thể đã thấy trước
đây, và cần một chút thời gian để làm quen, đó là "block" và iterator.
Thay vì lặp qua một chỉ số (như với C, C++, hoặc Java trước phiên bản 1.5),
hoặc lặp qua một danh sách (như `for (@a) {...}` của Perl, hoặc
`for i in aList: ...` của Python), với Ruby bạn sẽ thường thấy

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">some_list</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">this_item</span><span class="o">|</span>
  <span class="c1"># We're inside the block.</span>
  <span class="c1"># deal with this_item.</span>
<span class="k">end</span></code></pre></figure>

Để biết thêm thông tin về `each` (và các hàm liên quan `collect`, `find`,
`inject`, `sort`, v.v.), hãy xem `ri Enumerable`
(và sau đó `ri Enumerable#some_method`).

### Mọi thứ đều có giá trị

Không có sự khác biệt giữa biểu thức và câu lệnh. Mọi thứ
đều có giá trị, ngay cả khi giá trị đó là `nil`. Điều này hoàn toàn hợp lệ:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">y</span> <span class="o">=</span> <span class="mi">11</span>
<span class="n">z</span> <span class="o">=</span> <span class="k">if</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span>
      <span class="kp">true</span>
    <span class="k">else</span>
      <span class="kp">false</span>
    <span class="k">end</span>
<span class="n">z</span> <span class="c1"># =&gt; true</span></code></pre></figure>

### Symbol không phải là String nhẹ

Nhiều người mới học Ruby gặp khó khăn trong việc hiểu Symbol là gì và
chúng có thể được sử dụng để làm gì.

Symbol có thể được mô tả tốt nhất như là định danh. Một symbol quan trọng
ở **nó là ai**, không phải **nó là gì**. Hãy mở `irb` lên và xem sự
khác biệt:

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):001:0&gt;</span><span class="w"> </span><span class="ss">:george</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="ss">:george</span><span class="p">.</span><span class="nf">object_id</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):002:0&gt;</span><span class="w"> </span><span class="s2">"george"</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="s2">"george"</span><span class="p">.</span><span class="nf">object_id</span>
<span class="p">=&gt;</span> <span class="kp">false</span>
<span class="gp">irb(main):003:0&gt;</span></code></pre></figure>

Phương thức `object_id` trả về định danh của một Object. Nếu hai
đối tượng có cùng `object_id`, chúng là một (trỏ đến cùng một
Object trong bộ nhớ).

Như bạn thấy, khi bạn đã sử dụng một Symbol, bất kỳ Symbol nào có cùng
ký tự đều tham chiếu đến cùng một Object trong bộ nhớ. Với bất kỳ hai
Symbol nào đại diện cho cùng các ký tự, `object_id` của chúng khớp nhau.

Bây giờ hãy nhìn vào String ("george"). Các `object_id` không khớp nhau.
Điều đó có nghĩa là chúng đang tham chiếu đến hai đối tượng khác nhau
trong bộ nhớ. Mỗi khi bạn sử dụng một String mới, Ruby cấp phát bộ nhớ
cho nó.

Nếu bạn phân vân nên sử dụng Symbol hay String, hãy xem xét điều gì
quan trọng hơn: định danh của một đối tượng (ví dụ: một khóa Hash), hay
nội dung (trong ví dụ trên, "george").

### Mọi thứ đều là Object

"Mọi thứ đều là object" không chỉ là cường điệu. Ngay cả các lớp và
số nguyên cũng là object, và bạn có thể làm những điều tương tự với chúng
như với bất kỳ object nào khác:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># This is the same as</span>
<span class="c1"># class MyClass</span>
<span class="c1">#   attr_accessor :instance_var</span>
<span class="c1"># end</span>
<span class="no">MyClass</span> <span class="o">=</span> <span class="no">Class</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
  <span class="nb">attr_accessor</span> <span class="ss">:instance_var</span>
<span class="k">end</span></code></pre></figure>

### Hằng số có thể thay đổi

Hằng số không thực sự là hằng số. Nếu bạn thay đổi một hằng số đã được
khởi tạo, nó sẽ kích hoạt cảnh báo, nhưng không dừng chương trình của bạn.
Tuy nhiên, điều đó không có nghĩa là bạn **nên** định nghĩa lại hằng số.

### Quy ước đặt tên

Ruby áp dụng một số quy ước đặt tên. Nếu một định danh bắt đầu bằng
chữ hoa, nó là hằng số. Nếu nó bắt đầu bằng dấu đô la (`$`), nó là
biến toàn cục. Nếu nó bắt đầu bằng `@`, nó là biến instance. Nếu nó
bắt đầu bằng `@@`, nó là biến lớp.

Tuy nhiên, tên phương thức được phép bắt đầu bằng chữ hoa. Điều này
có thể gây nhầm lẫn, như ví dụ dưới đây cho thấy:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="no">Constant</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">def</span> <span class="nf">Constant</span>
  <span class="mi">11</span>
<span class="k">end</span></code></pre></figure>

Bây giờ `Constant` là 10, nhưng `Constant()` là 11.

### Tham số từ khóa

Giống như Python, từ Ruby 2.0 các phương thức có thể được định nghĩa
sử dụng tham số từ khóa:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">deliver</span><span class="p">(</span><span class="ss">from: </span><span class="s2">"A"</span><span class="p">,</span> <span class="ss">to: </span><span class="kp">nil</span><span class="p">,</span> <span class="ss">via: </span><span class="s2">"mail"</span><span class="p">)</span>
  <span class="s2">"Sending from </span><span class="si">#{</span><span class="n">from</span><span class="si">}</span><span class="s2"> to </span><span class="si">#{</span><span class="n">to</span><span class="si">}</span><span class="s2"> via </span><span class="si">#{</span><span class="n">via</span><span class="si">}</span><span class="s2">."</span>
<span class="k">end</span>

<span class="n">deliver</span><span class="p">(</span><span class="ss">to: </span><span class="s2">"B"</span><span class="p">)</span>
<span class="c1"># =&gt; "Sending from A to B via mail."</span>
<span class="n">deliver</span><span class="p">(</span><span class="ss">via: </span><span class="s2">"Pony Express"</span><span class="p">,</span> <span class="ss">from: </span><span class="s2">"B"</span><span class="p">,</span> <span class="ss">to: </span><span class="s2">"A"</span><span class="p">)</span>
<span class="c1"># =&gt; "Sending from B to A via Pony Express."</span></code></pre></figure>

### Sự thật tuyệt đối

Trong Ruby, mọi thứ trừ `nil` và `false` đều được coi là true. Trong
C, Python và nhiều ngôn ngữ khác, 0 và có thể các giá trị khác, chẳng hạn
như danh sách rỗng, được coi là false. Hãy xem đoạn mã Python sau
(ví dụ cũng áp dụng cho các ngôn ngữ khác):

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1"># in Python
</span><span class="k">if</span> <span class="mi">0</span><span class="p">:</span>
  <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">0 is true</span><span class="sh">"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
  <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">0 is false</span><span class="sh">"</span><span class="p">)</span></code></pre></figure>

Đoạn mã này sẽ in ra "0 is false". Tương đương trong Ruby:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># in Ruby</span>
<span class="k">if</span> <span class="mi">0</span>
  <span class="nb">puts</span> <span class="s2">"0 is true"</span>
<span class="k">else</span>
  <span class="nb">puts</span> <span class="s2">"0 is false"</span>
<span class="k">end</span></code></pre></figure>

In ra "0 is true".

### Phạm vi truy cập áp dụng đến cuối phạm vi

Trong đoạn mã Ruby sau,

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MyClass</span>
  <span class="kp">private</span>
  <span class="k">def</span> <span class="nf">a_method</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span>
  <span class="k">def</span> <span class="nf">another_method</span><span class="p">;</span> <span class="kp">false</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Bạn có thể nghĩ rằng `another_method` là public. Nhưng không phải vậy.
Bộ điều chỉnh truy cập `private` tiếp tục có hiệu lực cho đến cuối
phạm vi, hoặc cho đến khi một bộ điều chỉnh truy cập khác xuất hiện,
tùy điều nào đến trước. Mặc định, các phương thức là public:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MyClass</span>
  <span class="c1"># Now a_method is public</span>
  <span class="k">def</span> <span class="nf">a_method</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span>

  <span class="kp">private</span>

  <span class="c1"># another_method is private</span>
  <span class="k">def</span> <span class="nf">another_method</span><span class="p">;</span> <span class="kp">false</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

`public`, `private` và `protected` thực ra là các phương thức, vì vậy chúng
có thể nhận tham số. Nếu bạn truyền một Symbol cho một trong số chúng,
phạm vi truy cập của phương thức đó sẽ được thay đổi.

### Quyền truy cập phương thức

Trong Java, `public` có nghĩa là phương thức có thể được truy cập bởi
bất kỳ ai. `protected` có nghĩa là các instance của lớp, các instance
của lớp con, và các instance của các lớp trong cùng package có thể truy
cập, nhưng không ai khác, và `private` có nghĩa là không ai ngoài các
instance của lớp có thể truy cập phương thức.

Ruby có một chút khác biệt. `public` thì tự nhiên là public. `private`
có nghĩa là phương thức chỉ có thể được truy cập khi chúng có thể được
gọi mà không cần bộ nhận (receiver) tường minh. Chỉ `self` được phép
là bộ nhận của lệnh gọi phương thức private.

`protected` là cái cần chú ý. Một phương thức protected có thể được gọi
từ các instance của lớp hoặc lớp con, nhưng cũng có thể với một instance
khác làm bộ nhận.
Đây là một ví dụ (chuyển thể từ [The Ruby Language FAQ][faq]):

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Test</span>
  <span class="c1"># public by default</span>
  <span class="k">def</span> <span class="nf">identifier</span>
    <span class="mi">99</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="n">identifier</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="nf">identifier</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">=</span> <span class="no">Test</span><span class="p">.</span><span class="nf">new</span>  <span class="c1"># =&gt; #&lt;Test:0x34ab50&gt;</span>
<span class="n">t2</span> <span class="o">=</span> <span class="no">Test</span><span class="p">.</span><span class="nf">new</span>  <span class="c1"># =&gt; #&lt;Test:0x342784&gt;</span>
<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>       <span class="c1"># =&gt; true</span>

<span class="c1"># now make `identifier' protected; it still works</span>
<span class="c1"># because protected allows `other' as receiver</span>

<span class="k">class</span> <span class="nc">Test</span>
  <span class="kp">protected</span> <span class="ss">:identifier</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>  <span class="c1"># =&gt; true</span>

<span class="c1"># now make `identifier' private</span>

<span class="k">class</span> <span class="nc">Test</span>
  <span class="kp">private</span> <span class="ss">:identifier</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>
<span class="c1"># NoMethodError: private method `identifier' called for #&lt;Test:0x342784&gt;</span></code></pre></figure>

### Lớp mở

Các lớp trong Ruby là mở. Bạn có thể mở chúng ra, thêm vào, và thay đổi
chúng bất cứ lúc nào. Ngay cả các lớp lõi, như `Integer` hoặc thậm chí
`Object`, lớp cha của tất cả các đối tượng. Ruby on Rails định nghĩa
nhiều phương thức xử lý thời gian trên `Integer`. Hãy xem:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Integer</span>
  <span class="k">def</span> <span class="nf">hours</span>
    <span class="nb">self</span> <span class="o">*</span> <span class="mi">3600</span> <span class="c1"># number of seconds in an hour</span>
  <span class="k">end</span>
  <span class="k">alias</span> <span class="n">hour</span> <span class="n">hours</span>
<span class="k">end</span>

<span class="c1"># 14 hours from 00:00 January 1st</span>
<span class="c1"># (aka when you finally wake up ;)</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">mktime</span><span class="p">(</span><span class="mi">2006</span><span class="p">,</span> <span class="mo">01</span><span class="p">,</span> <span class="mo">01</span><span class="p">)</span> <span class="o">+</span> <span class="mi">14</span><span class="p">.</span><span class="nf">hours</span> <span class="c1"># =&gt; Sun Jan 01 14:00:00</span></code></pre></figure>

### Tên phương thức thú vị

Trong Ruby, các phương thức được phép kết thúc bằng dấu hỏi hoặc dấu chấm
than. Theo quy ước, các phương thức trả lời câu hỏi kết thúc bằng dấu hỏi
(ví dụ `Array#empty?`, trả về `true` nếu bộ nhận rỗng). Các phương thức
có thể "nguy hiểm" theo quy ước kết thúc bằng dấu chấm than (ví dụ
các phương thức thay đổi `self` hoặc các tham số, `exit!`, v.v.).
Tuy nhiên, không phải tất cả các phương thức thay đổi tham số đều kết thúc
bằng dấu chấm than. `Array#replace` thay thế nội dung của một mảng bằng
nội dung của một mảng khác. Sẽ không hợp lý nếu có một phương thức như vậy
mà lại **không** thay đổi self.

### Phương thức singleton

Phương thức singleton là các phương thức dành riêng cho từng đối tượng.
Chúng chỉ có sẵn trên Object mà bạn đã định nghĩa nó.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Car</span>
  <span class="k">def</span> <span class="nf">inspect</span>
    <span class="s2">"Cheap car"</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">porsche</span> <span class="o">=</span> <span class="no">Car</span><span class="p">.</span><span class="nf">new</span>
<span class="n">porsche</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Cheap car</span>
<span class="k">def</span> <span class="nc">porsche</span><span class="o">.</span><span class="nf">inspect</span>
  <span class="s2">"Expensive car"</span>
<span class="k">end</span>

<span class="n">porsche</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Expensive car</span>

<span class="c1"># Other objects are not affected</span>
<span class="n">other_car</span> <span class="o">=</span> <span class="no">Car</span><span class="p">.</span><span class="nf">new</span>
<span class="n">other_car</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Cheap car</span></code></pre></figure>

### Phương thức bị thiếu

Ruby không bỏ cuộc nếu nó không tìm thấy phương thức phản hồi một
thông điệp cụ thể. Nó gọi phương thức `method_missing` với tên của
phương thức không tìm thấy và các tham số. Mặc định, `method_missing`
ném ra ngoại lệ NameError, nhưng bạn có thể định nghĩa lại nó cho phù
hợp với ứng dụng của bạn, và nhiều thư viện làm như vậy. Đây là một ví dụ:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># id is the name of the method called, the * syntax collects</span>
<span class="c1"># all the arguments in an array named 'arguments'</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="s2">"Method </span><span class="si">#{</span><span class="nb">id</span><span class="si">}</span><span class="s2"> was called, but not found. It has "</span> <span class="o">+</span>
       <span class="s2">"these arguments: </span><span class="si">#{</span><span class="n">arguments</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>

<span class="n">__</span> <span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">,</span> <span class="mi">10</span>
<span class="c1"># =&gt; Method __ was called, but not found. It has these</span>
<span class="c1"># arguments: a, b, 10</span></code></pre></figure>

Đoạn mã trên chỉ in ra chi tiết của lệnh gọi, nhưng bạn hoàn toàn
tự do xử lý thông điệp theo bất kỳ cách nào phù hợp.

### Truyền thông điệp, không phải gọi hàm

Một lệnh gọi phương thức thực chất là một **thông điệp** gửi đến đối
tượng khác:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># This</span>
<span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span>
<span class="c1"># Is the same as this ...</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">+</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="c1"># Which is the same as this:</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">send</span> <span class="s2">"+"</span><span class="p">,</span> <span class="mi">2</span></code></pre></figure>

### Block là Object, chúng chỉ chưa biết điều đó

Block (thực chất là closure) được sử dụng rất nhiều bởi thư viện chuẩn.
Để gọi một block, bạn có thể sử dụng `yield`, hoặc biến nó thành `Proc`
bằng cách thêm một tham số đặc biệt vào danh sách tham số, như sau:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">block</span><span class="p">(</span><span class="o">&amp;</span><span class="n">the_block</span><span class="p">)</span>
  <span class="c1"># Inside here, the_block is the block passed to the method</span>
  <span class="n">the_block</span> <span class="c1"># return the block</span>
<span class="k">end</span>
<span class="n">adder</span> <span class="o">=</span> <span class="n">block</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="p">}</span>
<span class="c1"># adder is now a Proc object</span>
<span class="n">adder</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># =&gt; Proc</span></code></pre></figure>

Bạn cũng có thể tạo block bên ngoài lệnh gọi phương thức bằng cách gọi
`Proc.new` với một block hoặc gọi phương thức `lambda`.

Tương tự, các phương thức cũng là Object đang hình thành:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="nb">method</span><span class="p">(</span><span class="ss">:puts</span><span class="p">).</span><span class="nf">call</span> <span class="s2">"puts is an object!"</span>
<span class="c1"># =&gt; puts is an object!</span></code></pre></figure>

### Toán tử là cú pháp ngọt

Hầu hết các toán tử trong Ruby chỉ là cú pháp ngọt (syntactic sugar)
(với một số quy tắc ưu tiên) cho lệnh gọi phương thức. Ví dụ, bạn có thể
ghi đè phương thức `+` của Integer:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Integer</span>
  <span class="c1"># You can, but please don't do this</span>
  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="nb">self</span> <span class="o">-</span> <span class="n">other</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Bạn không cần `operator+` của C++, v.v.

Bạn thậm chí có thể có truy cập kiểu mảng nếu bạn định nghĩa các phương
thức `[]` và `[]=`. Để định nghĩa toán tử một ngôi + và - (ví dụ +1 và -2),
bạn phải định nghĩa các phương thức `+@` và `-@`, tương ứng. Tuy nhiên,
các toán tử dưới đây **không** phải là cú pháp ngọt. Chúng không phải là
phương thức, và không thể được định nghĩa lại:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="o">=</span><span class="p">,</span> <span class="o">..</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="ow">not</span><span class="p">,</span> <span class="o">&amp;&amp;</span><span class="p">,</span> <span class="ow">and</span><span class="p">,</span> <span class="o">||</span><span class="p">,</span> <span class="ow">or</span><span class="p">,</span> <span class="o">::</span></code></pre></figure>

Ngoài ra, `+=`, `*=` v.v. chỉ là viết tắt cho `var = var + other_var`,
`var = var * other_var`, v.v. và do đó không thể được định nghĩa lại.

## Tìm hiểu thêm

Khi bạn đã sẵn sàng để tìm hiểu thêm về Ruby, hãy xem phần
[Tài liệu](/vi/documentation/) của chúng tôi.



[faq]: http://ruby-doc.org/docs/ruby-doc-bundle/FAQ/FAQ.html
