Tra cứu hằng số

Một phần của tài liệu Tìm hiểu ngôn ngữ lập trình Ruby (Trang 36 - 39)

Chương V : Lớp và Module

3. Tra cứu hằng số

Khi một hằng số được tham chiếu đến mà không phân loại được một namespace nào, trình thơng dịch Ruby phải tìm định nghĩa mà tương thích với hằng số đó. Để làm như vậy, nó sử dụng một thuật tốn phân giải tên, giống như làm với định nghĩa phương thức. Tuy nhiên, các hằng số được phân giải theo cách rất khác với các phương thức.

Ruby đầu tiên sẽ cố gắng phân giải một tham chiếu hằng số trong phạm vi từ vựng của tham chiếu. Điều này có nghĩa là đầu tiên nó sẽ kiểm tra lớ hoặc module mà chứa tham chiếu hằng số đó để xem lớp hoặc hằng số đó có định nghĩa hằng số đó khơng. Nếu khơng, nó kiểm tra lớp hoặc module bao ngồi tiếp theo. Lưu ý rằng các hằng số ở cấp cao nhất hay “tồn cục” khơng được coi là một phần của phạm vi từ vựng và không được xem xét trong phần này của quá trính tra cứu. Phương thức lớp Module.nesting trả về danh sách các lớp và module được tìm kiếm trong bước này, theo thứ tự chúng được tìm kiếm.

Bài tập lớn Nguyên lý các ngơn ngữ lập trình – Tìm hiểu về Ruby

Nếu khơng định nghĩa hằng số nào được tìm thấy trong phạm vi từ vựng bao quanh, Ruby tiếp tục cố gắng để phân giải hằng số trong cây thừa kết bằng việc kiểm tra các tổ tiên của lớp hoặc module đó. Phương thức ancestors của lớp hoặc module chứa trả về danh sách các lớp và module được tìm kiếm trong bước này. Nếu khơng định nghĩa hằng số nào được tìm thấy trong cây thừa kế, các định nghĩa hằng số cấp cao nhất sẽ được kiểm tra.

Nếu khơng định nghĩa nào có thể tìm thấy cho hằng số cần tìm, thì phương thức const_missing - nếu có – của lớp hoặc module chứa được gọi và được tạo cơ hội để cung cấp một giá trị cho hằng số.

Có một vài điểm trong thuật tốn tra cứu hằng số này mà cần phải lưu ý chi tiết: - Hằng số được định nghĩa trong module bao trùm được tìm thấy thay vì hằng số được định nghĩa trong các module được bao gồm.

- Các module được bao gồm bởi một lớp được tìm kiếm trước lớp cha của lớp đó.

- Lớp Object là một phần của cây thừa kế. Các hằng số cấp cao nhất, được định nghĩa bên ngoài bất kỳ lớp hoặc module nào, giống như các phương thức cấp cao nhất: chúng được định nghĩa ngầm trong Object. Do đó, khi một hằng số cấp cao nhất được tham chiếu trong một lớp, nó được phân giải qua quá trình tìm kiếm cây thừa kế. Tuy nhiên, nếu hằng số được tham chiếu bên trong một định nghĩa module, cần có một phép kiểm tra tường minh trên Object sau khi tìm kiếm các tổ tiên của module đó.

- Module Kernel là một tổ tiên của Object. Điều này có nghĩa là các hằng số được định nghĩa trong Kernel hành động như các hằng số cấp cao nhất, nhưng có thể bị chồng lên bởi các hằng số cấp cao nhất thực, mà được định nghĩa trong Object.

Ví dụ dưới đây định nghĩa và phân giải các hằng số trong sáu phạm vi khác nhau và mô tả thuật tốn phân giải tên hằng số mơ tả ở trên.

Ví dụ : Phân giải tên hằng số

module Kernel

# Các hằng số được định nghĩa trong Kernel

A = B = C = D = E = F = "defined in kernel" end

# Các hằng số cấp cao nhất hay “toàn cục” được định nghĩa trong Object

A = B = C = D = E = "defined at toplevel" class Super

# Các hằng số được định nghĩa trong lớp cha

A = B = C = D = "defined in superclass"

end

module Included

# Các hằng số được định nghĩa trong một module được bao gồm

A = B = C = "defined in included module" end

module Enclosing

# Các hằng số được định nghĩa trong một module bao quanh

A = B = "defined in enclosing module" class Local < Super

include Included

# Hằng số được định nghĩa cục bộ

A = "defined locally"

# Danh sách các module được tìm kiếm, theo thứ tự tìm kiếm # [Enclosing::Local, Enclosing, Included, Super, Object, Kernel]

search = (Module.nesting + self.ancestors + Object.ancestors).uniq

puts A # In ra "defined locally"

puts B # In ra "defined in enclosing module" puts C # In ra "defined in included module" puts D # In ra "defined in superclass"

puts E # In ra "defined at toplevel" puts F # In ra "defined in kernel" end

end

def test

puts "entering method"

p = Proc.new { puts "entering proc"; return } p.call

puts "exiting method" # Dịng này khơng được thực hiện end

Bài tập lớn Nguyên lý các ngơn ngữ lập trình – Tìm hiểu về Ruby

Tài liệu tham khảo

1. David Flanagan & Yukihiro Matsumoto – The Ruby Progamming

Language – O’Reilly, 2008.

2. Yukihiro Matsumoto – Ruby in a nutshell, a Desktop quick reference – O’Reilly, 2001.

3. Peter Cooper – Beginning Ruby: From Novice to Professional, Second

Edition – 2009.

4. Chris Pine – Learn to Program, Second Edition – 2009.

5. David Thomas, Andrew Hunt, Dave Thomas – Progamming Ruby: The

Một phần của tài liệu Tìm hiểu ngôn ngữ lập trình Ruby (Trang 36 - 39)