Lập trình · Ngôn ngữ lập trình
Hướng dẫn học lập trình Ruby cơ bản cho người mới
Trả lời nhanh
Ruby là ngôn ngữ kịch bản động, hướng đối tượng, được thiết kế để đọc và viết dễ chịu. Lưu puts "Hello, world" vào hello.rb rồi chạy ruby hello.rb. Mọi thứ trong Ruby đều là đối tượng, kể cả số và nil. Các ý tưởng cốt lõi là phương thức định nghĩa bằng def, mảng và hash, block truyền cho các iterator như each và map, lớp và module, cùng ngoại lệ xử lý bằng begin/rescue.
Ruby là gì và dùng để làm gì
Ruby do Yukihiro Matsumoto ("Matz") tạo ra tại Nhật Bản và phát hành lần đầu năm 1995, với mục tiêu làm cho lập trình viên hạnh phúc. Ruby nổi tiếng nhờ Ruby on Rails, framework web đứng sau các trang như GitHub và Shopify. Ruby được dùng cho ứng dụng web, viết script, tự động hóa và các công cụ cho lập trình viên như Homebrew và CocoaPods. Bản triển khai tiêu chuẩn là CRuby (còn gọi là MRI).
Cài Ruby và chạy Hello, world
macOS và nhiều hệ thống Linux đã có sẵn Ruby, nhưng thường là bản cũ; hãy cài Ruby 3 mới bằng trình quản lý phiên bản như rbenv, asdf hoặc mise, hoặc dùng RubyInstaller trên Windows. Kiểm tra bằng ruby -v.
puts "Hello, world"ruby hello.rb
# Hello, world
irb # interactive Ruby shellputs in một giá trị kèm ký tự xuống dòng. Dấu ngoặc quanh đối số của phương thức là tùy chọn khi ý nghĩa đã rõ.
Biến và các kiểu dữ liệu cơ bản
Biến không cần khai báo và có thể chứa bất kỳ đối tượng nào. Theo quy ước, tên dùng snake_case. Hằng số bắt đầu bằng chữ cái viết hoa.
| Lớp | Ví dụ | Ghi chú |
|---|---|---|
Integer | 42, 2**100 | Kích thước bất kỳ |
Float | 3.14 | Độ chính xác kép |
String | "hi #{name}", 'hi' | Có thể thay đổi; dấu nháy kép nội suy biến |
Symbol | :name | Định danh bất biến, thường dùng làm khóa hash |
true, false | true | Chỉ false và nil được coi là sai |
NilClass | nil | Không có giá trị |
Array, Hash | [1, 2], {a: 1} | Các collection dựng sẵn |
name = "Ada"
count = 7
puts "#{name} has #{count} items" # Ada has 7 items
puts count / 2, count / 2.0 # 3, then 3.5
puts "12".to_i + 1 # 13
puts 5.class, nil.to_a.inspect # Integer, then []
puts 0 ? "0 is truthy" : "falsy" # 0 is truthyĐiều khiển luồng
score = 72
if score >= 90
puts "A"
elsif score >= 70
puts "B" # B
else
puts "C"
end
puts "pass" unless score < 50 # statement modifier
3.times { |i| print i, " " } # 0 1 2
puts
n = 10
n /= 2 while n > 1
puts n # 1
kind = case "SAT"
when "SAT", "SUN" then "weekend"
else "weekday"
end
puts kind # weekendCác khối kết thúc bằng end thay vì dấu ngoặc nhọn. Mã Ruby thường được thụt lề 2 dấu cách.
Phương thức
Phương thức trả về giá trị của biểu thức cuối cùng, nên return thường không cần thiết. Theo quy ước, phương thức trả về boolean kết thúc bằng ?, còn phương thức thay đổi trực tiếp đối tượng nhận kết thúc bằng !.
def greet(name, greeting: "Hello")
"#{greeting}, #{name}!"
end
def total(*nums)
nums.sum
end
puts greet("Lin") # Hello, Lin!
puts greet("Lin", greeting: "Hi") # Hi, Lin!
puts total(1, 2, 3) # 6
puts 4.even?, "abc".upcase # true, then ABC
s = "hello"
s.upcase! # modifies s in place
puts s # HELLOMảng và hash
nums = [3, 1, 2]
nums << 5
p nums.sort, nums.first, nums.last # [1, 2, 3, 5] then 3 then 5
p nums.sort[1..2] # [2, 3]
ages = { "ann" => 31, "bob" => 25 }
ages["cy"] = 40
ages.each { |person, age| puts "#{person} is #{age}" }
p ages.fetch("zed", 0) # 0
user = { name: "Ann", city: "Oslo" } # symbol keys
p user[:name] # "Ann"p in dạng inspect của giá trị, rất tiện khi gỡ lỗi vì hiển thị cả dấu nháy và dấu ngoặc.
Tính năng đặc trưng: block và iterator
Block là một đoạn mã được truyền cho phương thức, viết bằng { ... } trên một dòng hoặc do ... end trên nhiều dòng. Ruby lặp chủ yếu qua block thay vì vòng lặp for, và các phương thức của Enumerable giúp biến đổi dữ liệu rất gọn.
nums = [1, 2, 3, 4, 5]
p nums.map { |n| n * n } # [1, 4, 9, 16, 25]
p nums.select(&:even?) # [2, 4]
p nums.reduce(0) { |sum, n| sum + n } # 15
p nums.each_slice(2).to_a # [[1, 2], [3, 4], [5]]
p %w[pear fig apple].sort_by(&:length) # ["fig", "pear", "apple"]
def twice
yield
yield
end
twice { puts "hi" } # prints hi two times&:even? là cách viết tắt của { |n| n.even? }. Phương thức do bạn viết nhận một block và gọi nó bằng yield.
Lớp và module
module Greeter
def hello
"Hello from #{name}"
end
end
class Account
include Greeter # mix in module methods
attr_reader :name, :balance
def initialize(name)
@name = name # @ marks an instance variable
@balance = 0
end
def deposit(amount)
raise ArgumentError, "amount must be positive" unless amount.positive?
@balance += amount
self
end
def to_s = "#{name}: #{balance}"
end
acc = Account.new("Ann")
acc.deposit(30).deposit(20)
puts acc # Ann: 50
puts acc.hello # Hello from Annattr_reader tạo ra các phương thức getter. Module gom các phương thức để có thể trộn (mix in) vào nhiều lớp, đây là cách Ruby thay cho đa kế thừa. Dạng một dòng def to_s = ... cần Ruby 3.0 trở lên.
Xử lý lỗi
def parse_age(text)
age = Integer(text) # raises ArgumentError on bad input
raise ArgumentError, "negative age" if age.negative?
age
end
begin
puts parse_age("41") # 41
puts parse_age("abc")
rescue ArgumentError => e
puts "error: #{e.message}" # error: invalid value for Integer(): "abc"
ensure
puts "done"
endrescue bắt ngoại lệ, còn ensure luôn được chạy. Bên trong một phương thức, bạn có thể viết rescue trực tiếp mà không cần begin.
Một chương trình hoàn chỉnh nhỏ: tần suất từ
path = ARGV.fetch(0) { abort "usage: ruby words.rb FILE" }
begin
text = File.read(path).downcase
rescue Errno::ENOENT
abort "file not found: #{path}"
end
counts = text.scan(/[a-z']+/).tally
counts.max_by(5) { |_word, n| n }.each do |word, n|
puts format("%5d %s", n, word)
endChạy bằng ruby words.rb notes.txt. tally đếm các phần tử giống nhau vào một hash, còn max_by(5) trả về năm mục có số đếm cao nhất.
Lỗi thường gặp của người mới
- Quên
endđể đóng khốiif,def,classhoặcdo. - Trộn lẫn khóa chuỗi và khóa symbol:
h["name"]vàh[:name]là hai khóa khác nhau. - Dùng dấu nháy đơn mà vẫn mong nội suy
#{}hoạt động. - Gọi phương thức có
!mà không nhận ra nó đã thay đổi đối tượng gốc. - Dùng Ruby hệ thống cũ thay vì phiên bản mới cài bằng trình quản lý phiên bản.
Học tiếp ở đâu
Bắt đầu với trang tài liệu trên ruby-lang.org, gồm phần hướng dẫn nhanh "Ruby in Twenty Minutes", và dùng docs.ruby-lang.org để tra cứu thư viện lõi và thư viện chuẩn. Học Bundler và gem để quản lý thư viện phụ thuộc, RSpec hoặc Minitest để kiểm thử, rồi đến Ruby on Rails nếu bạn muốn xây dựng ứng dụng web.
Câu hỏi thường gặp
Ruby còn được dùng không?
Có. Ruby on Rails vận hành nhiều sản phẩm web lâu đời, gồm GitHub và Shopify, và Ruby phổ biến trong viết script và công cụ cho lập trình viên. Ruby ít được chọn cho dự án mới hơn Python hay JavaScript, nhưng vẫn được phát triển tích cực.
Ruby khác Ruby on Rails thế nào?
Ruby là ngôn ngữ lập trình. Rails là framework web viết bằng Ruby, cung cấp định tuyến, truy cập cơ sở dữ liệu và mẫu trang.
Symbol trong Ruby là gì?
Symbol như :name là một định danh bất biến và duy nhất. Cùng một symbol luôn là cùng một đối tượng, nên rất hiệu quả cho khóa hash và tên tùy chọn.
Người mới nên học Ruby hay Python?
Cả hai đều là ngôn ngữ đầu tiên tốt với cú pháp dễ đọc. Python có phạm vi dùng rộng hơn, nhất là trong khoa học dữ liệu; Ruby rất giàu biểu đạt và mạnh trong phát triển web với Rails.