Menu
CoddyTech

Hằng số

Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 14 trên 57.

Một hằng số bắt đầu bằng chữ cái viết hoa và theo quy ước được viết bằng chữ in hoa. Khi được định nghĩa trong phần thân của một lớp, hằng số có thể được gọi bằng tên trong mọi phương thức của lớp đó. Ở bên ngoài lớp, bạn viết ClassName::NAME:

class Account
  MIN_BALANCE = -100

  def self.allowed?(balance)
    balance >= MIN_BALANCE
  end
end

puts Account::MIN_BALANCE
puts Account.allowed?(-50)
puts Account.allowed?(-150)

Đầu ra:

-100
true
false

Hằng số phù hợp với dữ liệu cố định mà cả lớp cùng sử dụng, chẳng hạn như các giới hạn hoặc bảng tra cứu. fetch trên hằng số hash sẽ phát sinh KeyError nếu gặp khóa không xác định, thay vì âm thầm trả về nil:

class Shipping
  RATES = { "standard" => 5, "express" => 12 }.freeze

  def self.cost(method)
    RATES.fetch(method)
  end
end

puts Shipping.cost("express")
begin
  Shipping.cost("drone")
rescue KeyError => e
  puts e.message
end

Đầu ra:

12
key not found: "drone"

Không thể trỏ tên hằng số đến một đối tượng mới mà không khiến Ruby in ra cảnh báo, nhưng bạn vẫn có thể thay đổi đối tượng mà hằng số đó chứa. freeze khiến bản thân đối tượng ở chế độ chỉ đọc, vì vậy thay đổi sẽ gây ra FrozenError:

class Palette
  COLORS = ["red", "green"].freeze
end

begin
  Palette::COLORS << "blue"
rescue FrozenError => e
  puts e.message
end
p Palette::COLORS
p Palette::COLORS.frozen?

Đầu ra:

can't modify frozen Array: ["red", "green"]
["red", "green"]
true

Hãy chọn dựa trên cách giá trị hoạt động. Giá trị không bao giờ thay đổi nên được đặt trong một hằng số đóng băng; trạng thái thay đổi khi chương trình chạy, chẳng hạn như bộ đếm, nên được đặt trong biến thực thể của lớp:

class Ticket
  PREFIX = "TK"                  # cố định: một hằng số (constant)
  @issued = 0                    # thay đổi: biến instance của lớp

  def self.next_code
    @issued += 1
    "#{PREFIX}-#{@issued}"
  end
end
challenge icon

Thử thách

Dễ

Hoàn thiện lớp Order. Lớp này có các hằng số RATES (một hash đã đóng băng: standard có giá 5, express có giá 12, pickup có giá 0) và FREE_FROM (50). initialize(total, method) phát sinh ArgumentError với unknown shipping: drone khi method không phải là khóa của RATES. shipping trả về 0 khi tổng tiền từ FREE_FROM trở lên, nếu không thì trả về mức phí tương ứng, còn to_s trả về 40.00 + 5 express = 45.00.

Code được cung cấp in ra free from 50 bằng hằng số, sau đó đọc các đơn hàng dưới dạng những dòng total method và in ra từng đơn hàng hoặc thông báo lỗi.

Code của bạn nằm trong order.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

require_relative 'order'

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
  input << line.chomp
end
puts "free from #{Order::FREE_FROM}"
input.each do |line|
  total, method = line.split
  begin
    puts Order.new(total.to_f, method)
  rescue ArgumentError => e
    puts e.message
  end
end
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Ruby online