diff options
Diffstat (limited to 'vi-vn')
-rw-r--r-- | vi-vn/json-vi.html.markdown | 76 | ||||
-rw-r--r-- | vi-vn/objective-c-vi.html.markdown | 2 | ||||
-rw-r--r-- | vi-vn/ruby-ecosystem-vi.html.markdown | 148 | ||||
-rw-r--r-- | vi-vn/ruby-vi.html.markdown | 549 |
4 files changed, 774 insertions, 1 deletions
diff --git a/vi-vn/json-vi.html.markdown b/vi-vn/json-vi.html.markdown new file mode 100644 index 00000000..257216ff --- /dev/null +++ b/vi-vn/json-vi.html.markdown @@ -0,0 +1,76 @@ +--- +language: json +filename: learnjson-vi.json +contributors: + - ["Anna Harren", "https://github.com/iirelu"] + - ["Marco Scannadinari", "https://github.com/marcoms"] + - ["himanshu", "https://github.com/himanshu81494"] +translators: + - ["Thanh Phan", "https://github.com/thanhpd"] +lang: vi-vn +--- + +Do JSON là một ngôn ngữ trao đổi dữ liệu hết sức đơn giản, đây có thể sẽ là bài +đơn giản nhất của Học X trong Y phút (Learn X in Y Minutes) từ trước tới nay. + +JSON ở dạng thuần túy nhất không có chú thích cho câu lệnh (comment) nào, nhưng +hầu hết các trình phân tích cú pháp (parser) đều chấp nhận chú thích theo phong +cách của ngôn ngữ C (`//`, `/* */`). Một số trình phân tích cú pháp còn chấp +nhận dấu phẩy cuối cùng (vd: một dấu phẩy sau phần tử cuối cùng của một mảng +hoặc sau thuộc tính cuối cùng của một object), nhưng những trường hợp này nên +tránh để có sự tương thích tốt hơn. + +Để phục vụ cho mục đích bài học này, tất cả cú pháp JSON ở đây sẽ đều là 100% hợp lệ. +May mắn thay, chúng cũng tự trình bày cho chính mình mà không cần thêm giải thích. + +Các kiểu dữ liệu được JSON hỗ trợ bao gồm: số (*numbers*), chuỗi kí tự +(*string*), toán tử đúng/sai (*boolean*), mảng (*array*), *object* và *null*. +Các trình duyệt hỗ trợ bao gồm: Mozilla Firefox phiên bản 3.5 trở lên, +Internet Explorer 8 trở lên, Google Chrome, Opera 10 trở lên, Safari 4 trở lên. +Kiểu tệp JSON có dạng ".json". Kiểu MIME (Multipurpose Internet Mail Extensions) +cho JSON là "application/json". Điểm yếu của JSON đó là thiếu các định dạng cho +kiểu dữ liệu cũng như quy chuẩn cú pháp chặt chẽ sử dụng DTD. + +```json +{ + "khóa": "dữ liệu", + + "các khóa": "phải luôn được đặt trong dấu ngoặc kép", + "số": 0, + "chuỗi kí tự": "Xin chàø. Tất cả kí tự unicode đều được chấp nhận, sử dụng với dạng \"kí tự\"." + "có đúng không?": true, + "không có gì": null, + + "số rất lớn": 1.2e+100, + + "objects": { + "chú thích": "Hầu hết các cấu trúc dữ liệu bạn sẽ dùng sẽ sử dụng object.", + + "mảng": [0, 1, 2, 3, "Mảng có thể chứa bất kì thứ gì bên trong.", 5], + + "một object khác": { + "chú thích": "Những thứ này có thể lồng vào nhau, rất tiện." + } + }, + + "ngớ ngẩn": [ + { + "nguồn cung cấp kali": ["chuối"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "neo"], + [0, 0, 0, 1] + ] + ], + + "phong cách khác": { + "chú thích": "kiểm tra cái này xem!" + , "vị trí dấu phẩy": "không quan trọng - chỉ cần nó ở trước khóa tiếp theo là được" + , "chú thích khác": "tiện phải không" + }, + + "nó rất ngắn": "Và bạn đã xong rồi đấy. Bạn đã biết tất cả những thứ mà JSON có thể cung cấp." +} +``` diff --git a/vi-vn/objective-c-vi.html.markdown b/vi-vn/objective-c-vi.html.markdown index c97bb560..38e418e9 100644 --- a/vi-vn/objective-c-vi.html.markdown +++ b/vi-vn/objective-c-vi.html.markdown @@ -12,7 +12,7 @@ filename: LearnObjectiveC-vi.m Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành OS X, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch.
Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
-```objective_c
+```objective-c
// Chú thích dòng đơn bắt đầu với //
/*
diff --git a/vi-vn/ruby-ecosystem-vi.html.markdown b/vi-vn/ruby-ecosystem-vi.html.markdown new file mode 100644 index 00000000..518cf072 --- /dev/null +++ b/vi-vn/ruby-ecosystem-vi.html.markdown @@ -0,0 +1,148 @@ +--- +category: tool +tool: ruby ecosystem +contributors: + - ["Jon Smock", "http://github.com/jonsmock"] + - ["Rafal Chmiel", "http://github.com/rafalchmiel"] + - ["Vinh Nguyen", "http://rubydaily.net"] +lang: vi-vn +--- + +Nhìn chung các lập trình viên Ruby luôn có cách để cài đặt các phiên bản +Ruby khác nhau, quản lý các gói (hoặc gems), và quản lý các thư viện. + +## Trình quản lý Ruby + +Một vài nền tảng phải có Ruby đã được cài đặt trước hoặc có sẵn như một gói. +Số đông lập trình viên Ruby không sử dụng cái này, hoặc nếu có, họ chỉ sử +dụng chúng để bootstrap cài đặt Ruby. Thay vào đó, các lập trình viên Ruby +có xu hướng cài đặt trình quản lý Ruby để cài đặt và chuyển đổi các phiên +bản của Ruby và môi trường Ruby cho dự án của họ. + +Dưới đây là các trình quản lý môi trường Ruby nổi tiếng: + +* [RVM](https://rvm.io/) - Cài đặt và chuyển đổi các phiên bản Ruby. RVM cũng + có các khái niệm về tập các gems để quản lý môi trường dự án một + cách tốt nhất. +* [ruby-build](https://github.com/sstephenson/ruby-build) - Chỉ cài đặt các + phiên bản Ruby. Sử dụng cái này giúp cho việc cài đặt Ruby tốt hơn. +* [rbenv](https://github.com/sstephenson/rbenv) - Chỉ dùng để chuyển đổi các + phiên bản Ruby. Được sử dụng đi kèm với ruby-build. Tiện ích này sẽ giúp + cho việc dùng Ruby tốt hơn. +* [chruby](https://github.com/postmodern/chruby) - Chỉ dùng để chuyển đổi các + phiên bản Ruby. Tương tự như rbenv. Không quan tâm làm thế nào Ruby được + cài đặt. + +## Các phiên bản Ruby + +Ruby được tạo ra bởi Yukihiro "Matz" Matsumoto, người được xem như là một +[BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), mặc dầu gần +đây luôn thay đổi. Kết quả là, tham chiếu của Ruby được gọi là MRI(Matz' +Reference Implementation), và khi bạn biết về một phiên bản Ruby, nó đang +được tham chiếu để phát hành một phiên bản của MRI. + +Có ba phiên bản Ruby chính thức được dùng là: + +* 2.0.0 - Được phát hành vào tháng 2 năm 2013. Hầu hết các thư viện lớn, và +nền tảng đều hỗ trợ 2.0.0. +* 1.9.3 - Được phát hành vào tháng 10 năm 2011. Đây là phiên bản hầu hết các +lập trình viên Ruby đang dùng. [Nhưng đã không còn hỗ trợ]( + https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended + /) +* 1.8.7 - [Ruby 1.8.7 đã không còn được sử dụng]( + http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/). + +Sự thay đổi giữa phiên bản 1.8.7 đến 1.9.x lớn hơn nhiều so với thay đổi từ +1.9.3 đến 2.0.0. Ví dụ, các phiên bản 1.9 giới thiệu các bảng mã và một +byecote VM. Có các dự án vẫn đang ở 1.8.7, nhưng chúng chiếm một số lượng ít +, phần lớn cộng đồng đã chuyển sang ít nhất là 1.9.2 hoặc 1.9.3 + +## Các ứng dụng Ruby + +Hệ sinh thái Ruby có rất nhiều ứng dụng, với mỗi thế mạnh độc đáo và khả +năng tương thích. Để rõ ràng hơn, sự khác nhau giữa các ứng dụng được viết +bằng các ngôn ngữ khác nhau, nhưng *chúng vẫn là Ruby*. +Mỗi ứng dụng có các hook đặc trưng và những tính năng đặc biệt, nhưng tất cả +đều chạy Ruby rất tốt. Ví dụ, JRuby được viết bằng Java, nhưng bạn không +cần biết Java để sử dụng. + +Một số ứng dụng nổi tiếng/tương thích cao: + +* [MRI](https://github.com/ruby/ruby) - Được viết bằng C, đây là ứng dụng + tham chiếu của Ruby. Nó tương thích 100%. Tất cả các phiên bản Ruby có khả + năng duy trì với MRI(xem [RubySpec](#rubyspec) bên dưới). +* [JRuby](http://jruby.org/) - Được viết bằng Java và Ruby, ứng dụng này khá + nhanh. Điểm mạnh quan trọng nhất của JRuby là JVM/Java interop, tận dụng + các công cụ, dự án và ngôn ngữ hiện có của JVM. +* [Rubinius](http://rubini.us/) - Được viết bằng ngôn ngữ chính là Ruby với + một C++ bytecode VM. Rất nhanh. Bởi vì nó được phát triển bằng chính Ruby. + +Một số ứng dụng khá nổi tiếng/tương thích: + +* [Maglev](http://maglev.github.io/) - Đứng đầu Gemstone, một Smalltalk VM. + SmallTalk có một vài tiện ích hấp dẫn, và trong dự án này đã mang nó vào + môi trường Ruby. +* [RubyMotion](http://www.rubymotion.com/) - Mang Ruby đến việc phát triển iOS. + +Một số ứng dụng tốt/tương thích: + +* [Topaz](http://topazruby.com/) - Được biết bằng RPython (sử dụng Pypy), + Topaz vẫn còn rất trẻ và chưa hoàn toàn tương thích. Nó hứa hẹn khả năng + trở thành một ứng dụng Ruby tương thích cao. +* [IronRuby](http://ironruby.net/) - Được viết bằng C# hướng đến nền tảng .NET + , IronRuby dường như đã dừng hoạt động kể từ khi Microsoft rút hỗ trợ. + +Các ứng dụng Ruby có các phiên bản riêng của mình, nhưng chúng luôn luôn +hướng đến sự một phiên bản đặc biệt của MRI cho sự tương thích. Nhiều ứng +dụng có khả năng đến các chế độ khác nhau (ví dụ, 1.8 hoặc 1.9) để hướng đến +phiên bản MRI. + +## RubySpec + +Hầu hết các ứng dụng Ruby dựa vào [RubySpec](http://rubyspec.org/). Ruby không +có thông báo chính thức, nhưng cộng đồng đã viết những specs thực thi trong +Ruby để kiểm tra sự tương thích với MRI. + +## RubyGems + +[RubyGems](http://rubygems.org/) là một cộng đồng quản lý các gói cho Ruby. +RubyGems đi kèm với Ruby, bởi vậy không cần cài đặt riêng lẻ. + +Các gói Ruby được gọi là "gems", và chúng được host bởi cộng đồng tại +RubyGems.org. Một gem chứa mã nguồn của nó và một vài mô tả, bao gồm những +thứ như phiên bản, các thư viện độc lập, các tác giả và các loại giấy phép. + +## Bundler + +[Bundler](http://bundler.io/) là một gem giải quyết độc lập. Nó sử dụng một +Gemfile để tìm kiếm các thư viện độc lập trong dự án, và sau đó sẽ lấy về +các thư viện của các thư viện độc lập này. Nó thực hiện cho đến khi việc +tải các thư viện hoàn tất, hoặc nó sẽ dừng nếu xuất hiện bất kỳ xung đột nào. + +Bundler sẽ hiển thị lỗi nếu tìm thấy bất kỳ xung đột giữa các thư viện. Ví +dụ, nếu như gem A yêu cầu gem Z có phiên bản 3 hoặc cao hơn, nhưng gem B lại +yêu cầu gem Z phiên bản 2. Bundler sẽ thông báo cho bạn sự xung đột này. +Điều này đã rất hữu ích khi nhiều gem tham chiếu các các gem khác (trong +gem này lại tham chiếu đến các gem khác nữa), có thể hình thành một đồ thị +lớn để nói. + +# Kiểm thử + +Kiểm thử là một phần lớn của Ruby. Ruby mang đến một nền tảng kiểm thử theo +kiểu Unit được gọi là minitest (hoặc TestUnit for phiên bản Ruby 1.8.x). +Có nhiều thư viện kiểm thử với các mục đích khác nhau. + +* [TestUnit](http://ruby-doc.org/stdlib-1.8.7/libdoc/test/unit/rdoc/Test/ + Unit.html) - Nền tảng kiểm thử theo kiểu Unit của Ruby 1.8. +* [minitest](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest + /rdoc/MiniTest.html) -Nền tảng kiểm thử được xây dựng cho Ruby 1.9/2.0 +* [RSpec](http://rspec.info/) - Một nền tảng kiểm thử tập trung vào sự + hoạt động. +* [Cucumber](http://cukes.info/) - Một nền tảng kiểm thử theo kiểu BDD dưới + định dạng Gherkin. + +## Be Nice + +Cộng đồng Ruby tự hào là một cộng đồng mở, đa dạng và chào đón tất cả mọi +người. Bản thân Matz là một người cực kỳ thân thiện, và các lập trình viên +Ruby rất tuyệt vời. diff --git a/vi-vn/ruby-vi.html.markdown b/vi-vn/ruby-vi.html.markdown new file mode 100644 index 00000000..73382100 --- /dev/null +++ b/vi-vn/ruby-vi.html.markdown @@ -0,0 +1,549 @@ +--- +language: ruby +filename: learnruby.rb +contributors: + - ["David Underwood", "http://theflyingdeveloper.com"] + - ["Joel Walden", "http://joelwalden.net"] + - ["Luke Holder", "http://twitter.com/lukeholder"] + - ["Tristan Hume", "http://thume.ca/"] + - ["Nick LaMuro", "https://github.com/NickLaMuro"] + - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"] + - ["Ariel Krakowski", "http://www.learneroo.com"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Levi Bostian", "https://github.com/levibostian"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Vinh Nguyen", "http://rubydaily.net"] +lang: vi-vn + +--- + +```ruby +# Đây là một comment + +=begin +Đây là một comment nhiều dòng +Không ai dùng cách này +Bạn không nên dùng +=end + +# Đầu tiên và quan trọng nhất: Mọi thứ là đối tượng. + +# Các con số là các đối tượng. + +3.class #=> Fixnum + +3.to_s #=> "3" + + +# Một vài bài toán số học căn bản +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 +35 / 5 #=> 7 +2**5 #=> 32 + +# Số học vừa là các cú pháp thân thiện cho việc gọi +# một hàm trên một đối tượng +1.+(3) #=> 4 +10.* 5 #=> 50 + +# Các giá trị đặc biệt là các đối tượng +nil # Ở đây không có gì để xem +true # luôn đúng +false # luôn sai + +nil.class #=> Lớp Nil +true.class #=> Lớp True +false.class #=> Lớp False + +# So sánh bằng +1 == 1 #=> true +2 == 1 #=> false + +# So sánh không bằng +1 != 1 #=> false +2 != 1 #=> true + +# Ngoài chính false, thì nil là một giá trị khác của false + +!nil #=> true +!false #=> true +!0 #=> false + +# Các loại so sánh khác +1 < 10 #=> true +1 > 10 #=> false +2 <= 2 #=> true +2 >= 2 #=> true + +# Các toán tử logic +true && false #=> false +true || false #=> true +!true #=> false + + +# Có các cách khác của các toán tử logic với mức thấp hơn +# Chúng được sử dụng như các cấu trúc điều khiển luồng nối các mệnh đề +# với nhau cho đến khi một trong số chúng trả về đúng hoặc sai. + +# `do_something_else` chỉ được gọi nếu như hàm `do_something` thành công. +do_something() and do_something_else() +# `log_error` chỉ được gọi nếu hàm `do_something` không thành công. +do_something() or log_error() + + +# Các chuỗi là các đối tượng + +'I am a string'.class #=> String +"I am a string too".class #=> String + +placeholder = 'use string interpolation' +"I can #{placeholder} when using double quoted strings" +#=> "I can use string interpolation when using double quoted strings" + +# Nên đưa các chuỗi vào trong dấu nháy đơn +# Ngoài ra dấu nháy kép được sử dụng trong tính toán. + +# Nối các chuỗi, nhưng không nối với các số. +'hello ' + 'world' #=> "hello world" +'hello ' + 3 #=> TypeError: can't convert Fixnum into String +'hello ' + 3.to_s #=> "hello 3" + +# Xuất ra ngoài màn hình +puts "I'm printing!" + +# Các biến +x = 25 #=> 25 +x #=> 25 + +# Chú ý về việc gán các giá trị được trả về vào biến. +# Điều này có nghĩa là bạn có thể gán nhiều biến. + +x = y = 10 #=> 10 +x #=> 10 +y #=> 10 + +# Theo quy ước, dùng snake_case cho các tên của biến. +snake_case = true + +# Dùng để mô tả tên các biến +path_to_project_root = '/good/name/' +path = '/bad/name/' + +# Ký tự (là các đối tượng) +# Các ký tự là bất biến, như các biến hằng số chỉ đến các số nguyên. +# Chúng thường xuyên được sử dụng thay cho các chuỗi để chuyển đổi các giá +# trị hiệu quả. + +:pending.class #=> Symbol + +status = :pending + +status == :pending #=> true + +status == 'pending' #=> false + +status == :approved #=> false + +# Các mảng + +# Đây là một mảng +array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] + +# Các mảng có thể chứa nhiều phần tử khác nhau + +[1, 'hello', false] #=> [1, "hello", false] + +# Có thể truy cập các giá trị của mảng thông qua các chỉ mục +array[0] #=> 1 +array[12] #=> nil + +# Giống như số học, sử dụng [biến] là một cú pháp thông dụng +array.[] 0 #=> 1 +array.[] 12 #=> nil + +# Lấy phần tử cuối cùng +array[-1] #=> 5 + +# Bắt đầu từ chỉ mục và số phần tử cần lấy +array[2, 3] #=> [3, 4, 5] + +# Đảo ngược một mảng +a=[1,2,3] +a.reverse! #=> [3,2,1] + +# Lấy một khoảng +array[1..3] #=> [2, 3, 4] + +# Thêm phần tử vào mảng bằng cách này +array << 6 #=> [1, 2, 3, 4, 5, 6] +# Hoặc cách này +array.push(6) #=> [1, 2, 3, 4, 5, 6] + +# Kiểm tra phần tử có tồn tại trong mảng +array.include?(1) #=> true + +# Băm là phần chính của Ruby với các cặp khoá/giá trị +# Băm được biểu thị bằng dấu ngoặc nhọn: +hash = { 'color' => 'green', 'number' => 5 } + +hash.keys #=> ['color', 'number'] + +# Băm có thể được truy cập nhanh chóng thông qua khoá +hash['color'] #=> 'green' +hash['number'] #=> 5 + +# Khoá không tồn tại sẽ trả về nil +hash['nothing here'] #=> nil + +# Kể từ Ruby bản 1.9, đây là một cú pháp đặc biệt, sử dụng symbol như khoá + +new_hash = { defcon: 3, action: true } + +new_hash.keys #=> [:defcon, :action] + +# Kiểm tra khoá hoặc giá trị có tồn tại hay không +new_hash.has_key?(:defcon) #=> true +new_hash.has_value?(3) #=> true + +# Mẹo: Cả Mảng và Băm đều là Enumberable +# Chúng cùng chia sẻ rất nhiều phương thức hữu ích như each, map, count... + +# Cấu trúc điều khiển + +if true + 'if statement' +elsif false + 'else if, optional' +else + 'else, also optional' +end + +for counter in 1..5 + puts "iteration #{counter}" +end +#=> iteration 1 +#=> iteration 2 +#=> iteration 3 +#=> iteration 4 +#=> iteration 5 + +# TUY NHIÊN, không ai sử dụng vòng lặp for. +# Thay vào đó, ban nên dùng phương thức "each" và truyền vào đó một khối. +# Một khối là một loạt các mã mà bạn có thể truyền +# cho một phương thức giống như each. +# Nó tương tự với lambda, các hàm ẩn danh hoặc closures trong các ngôn ngữ +# lập trình khác. +# +# Phương thức "each" cho một khoản sẽ chạy qua từng phần tử của khoảng đó. +# Khối được truyền vào là một số đếm như là tham số. +# Gọi một method "each" với một khối sẽ trông như thế này: + +(1..5).each do |counter| + puts "iteration #{counter}" +end +#=> iteration 1 +#=> iteration 2 +#=> iteration 3 +#=> iteration 4 +#=> iteration 5 + +# Bạn cũng có thể bao khối trong các dấu ngoặc nhọn. +(1..5).each { |counter| puts "iteration #{counter}" } + +# Các nội dung của cấu trúc dữ liệu cũng có thể được lặp bằng each. +array.each do |element| + puts "#{element} is part of the array" +end +hash.each do |key, value| + puts "#{key} is #{value}" +end + +counter = 1 +while counter <= 5 do + puts "iteration #{counter}" + counter += 1 +end +#=> iteration 1 +#=> iteration 2 +#=> iteration 3 +#=> iteration 4 +#=> iteration 5 + +grade = 'B' + +case grade +when 'A' + puts 'Way to go kiddo' +when 'B' + puts 'Better luck next time' +when 'C' + puts 'You can do better' +when 'D' + puts 'Scraping through' +when 'F' + puts 'You failed!' +else + puts 'Alternative grading system, eh?' +end +#=> "Better luck next time" + +# Cases cũng được dùng cho các dãy +grade = 82 +case grade +when 90..100 + puts 'Hooray!' +when 80...90 + puts 'OK job' +else + puts 'You failed!' +end +#=> "OK job" + +# Xử lý ngoại lệ: +begin + # Code ở đây có thể sẽ đưa ra một ngoại lệ. + raise NoMemoryError, 'You ran out of memory.' +rescue NoMemoryError => exception_variable + puts 'NoMemoryError was raised', exception_variable +rescue RuntimeError => other_exception_variable + puts 'RuntimeError was raised now' +else + puts 'This runs if no exceptions were thrown at all' +ensure + puts 'This code always runs no matter what' +end + +# Hàm + +def double(x) + x * 2 +end + +# Hàm (và tất cả các khối) được mặc định giá trị trả về ở mệnh đề cuối. +double(2) #=> 4 + +# Dấu ngoặc là một tuỳ chọn cho một kết quả rõ ràng. +double 3 #=> 6 + +double double 3 #=> 12 + +def sum(x, y) + x + y +end + +# Các đối số được chia cắt bởi dấu phẩy. +sum 3, 4 #=> 7 + +sum sum(3, 4), 5 #=> 12 + +# yield +# Tất cả các hàm có thể có một tham số tuỳ chọn. +# Nó có thể được gọi với từ khóa "yield". +def surround + puts '{' + yield + puts '}' +end + +surround { puts 'hello world' } + +# { +# hello world +# } + + +# Bạn có thể truyền một khối đến một hàm +# Dấu "&" được đánh dấu đến một khối +def guests(&block) + block.call 'some_argument' +end + +# Bạn có thể truyền một danh sách các tham số, nó sẽ được chuyển thành mảng. +# Thông qua việc sử dụng dấu *. +def guests(*array) + array.each { |guest| puts guest } +end + +# Định nghĩ một lớp thông qua từ khoá class. +class Human + + # Một biến class. Nó được chia sẽ cho tất cả các instance của lớp này. + @@species = 'H. sapiens' + + # Các khởi tạo căn bản + def initialize(name, age = 0) + # Gán đối số đến biến instance "name" + @name = name + # Nếu không có age, sẽ lấy giá trị mặc định trong danh sách đối số. + @age = age + end + + # Hàm nhập giá trị căn bản + def name=(name) + @name = name + end + + # Hàm lấy giá trị căn bản + def name + @name + end + + # Các hàm trên có thể được gọn lại bằng cách dùng hàm attr_accessor + attr_accessor :name + + # Các hàm nhận/lấy cũng có thể được tạo riêng như sau: + attr_reader :name + attr_writer :name + + # Một hàm lớp dùng self để phân biệt với hàm instance. + # Nó chỉ có thể được gọi trên lớp. + def self.say(msg) + puts msg + end + + def species + @@species + end +end + + +# Khởi tạo một lớp +jim = Human.new('Jim Halpert') + +dwight = Human.new('Dwight K. Schrute') + +# Hãy gọi một cặp các hàm. +jim.species #=> "H. sapiens" +jim.name #=> "Jim Halpert" +jim.name = "Jim Halpert II" #=> "Jim Halpert II" +jim.name #=> "Jim Halpert II" +dwight.species #=> "H. sapiens" +dwight.name #=> "Dwight K. Schrute" + +# Gọi một hàm lớp +Human.say('Hi') #=> "Hi" + +# Phạm vi của biến được định nghĩa bởi cách chúng ta đặt tên cho chúng. +# Các biến bắt đầu với dấu $ là biến toàn cục. +$var = "I'm a global var" +defined? $var #=> "global-variable" + +# Các biến bắt đầu với dấu @ là biến phạm vi. +@var = "I'm an instance var" +defined? @var #=> "instance-variable" + +# Các biến bắt đầu với dấu @@ có pham vi là trong một lớp. +@@var = "I'm a class var" +defined? @@var #=> "class variable" + +# Các biến bắt đầu với ký tự viết hoa là biến hằng. +Var = "I'm a constant" +defined? Var #=> "constant" + +# Lớp cũng là một đối tượng trong Ruby. Bởi vậy lớp có các biến instance. +# Biến lớp được chia sẽ trong lớp và các lớp kế thừa nó. + +# Lớp cơ sở +class Human + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(value) + @@foo = value + end +end + +# Lớp kế thừa +class Worker < Human +end + +Human.foo # 0 +Worker.foo # 0 + +Human.foo = 2 # 2 +Worker.foo # 2 + +# Các biến lớp instance không được chia sẽ trong lớp kế thừa. + +class Human + @bar = 0 + + def self.bar + @bar + end + + def self.bar=(value) + @bar = value + end +end + +class Doctor < Human +end + +Human.bar # 0 +Doctor.bar # nil + +module ModuleExample + def foo + 'foo' + end +end + +# Include một module sẽ đưa các hàm của module thành instances của lớp. +# Extend một module sẽ đưa các hàm của module thành các biến của lớp. + +class Person + include ModuleExample +end + +class Book + extend ModuleExample +end + +Person.foo # => NoMethodError: undefined method `foo' for Person:Class +Person.new.foo # => 'foo' +Book.foo # => 'foo' +Book.new.foo # => NoMethodError: undefined method `foo' + +# Hàm hồi quy được thực hiện khi include và extend một module. + +module ConcernExample + def self.included(base) + base.extend(ClassMethods) + base.send(:include, InstanceMethods) + end + + module ClassMethods + def bar + 'bar' + end + end + + module InstanceMethods + def qux + 'qux' + end + end +end + +class Something + include ConcernExample +end + +Something.bar # => 'bar' +Something.qux # => NoMethodError: undefined method `qux' +Something.new.bar # => NoMethodError: undefined method `bar' +Something.new.qux # => 'qux' +``` + +## Các nguồn tham khảo thêm. + +- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges. +- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/) +- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/) +- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online. +- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide. |