Trong Ruby, hầu hết các biến chưa được khởi tạo hoặc thậm chí không tồn tại được đánh giá là nil
. Điều này đúng cho các biến địa phương, các biến dụ và các biến toàn cầu:
defined? foo #=> nil
local_variables #=> []
if false
foo = 42
end
defined? foo #=> 'local-variable'
local_variables #=> [:foo]
foo #=> nil
foo.nil? #=> true
defined? @bar #=> nil
instance_variables #=> []
@bar #=> nil
@bar.nil? #=> true
# warning: instance variable @bar not initialized
defined? $baz #=> nil
$baz #=> nil
# warning: global variable `$baz' not initialized
$baz.nil? #=> true
# warning: global variable `$baz' not initialized
Đó là, tuy nhiên, không đúng sự thật cho các biến hệ thống phân cấp lớp và các hằng số:
defined? @@wah #=> nil
@@wah
# NameError: uninitialized class variable @@wah in Object
defined? QUUX #=> nil
QUUX
# NameError: uninitialized constant Object::QUUX
Đây là một cá trích đỏ:
defined? fnord #=> nil
local_variables #=> []
fnord
# NameError: undefined local variable or method `fnord' for main:Object
Lý do tại sao bạn nhận được lỗi ở đây là không phải rằng các biến cục bộ được đơn vị hóa không đánh giá là nil
, đó là mũ fnord
không rõ ràng: có thể là hoặc thông báo ít đối số gửi tới người nhận mặc định (tức là tương đương với self.fnord()
) hoặc quyền truy cập vào biến cục bộ fnord
.
Để disambiguate đó, bạn cần phải thêm một máy thu hoặc một danh sách đối số (ngay cả khi có sản phẩm nào) nói của Ruby rằng đó là một gửi thông điệp:
self.fnord
# NoMethodError: undefined method `fnord' for main:Object
fnord()
# NoMethodError: undefined method `fnord' for main:Object
hoặc chắc chắn rằng phân tích cú pháp (không người đánh giá) phân tích (không thực thi) một bài tập trước khi sử dụng, để nói của Ruby rằng nó là một biến cục bộ:
if false
fnord = 42
end
fnord #=> nil
tại sao biến mẫu được xử lý khác với biến cục bộ và lớp?
Thực tế là không. Nó được xử lý giống như một biến cục bộ. Biến phân cấp lớp là biến hoạt động khác nhau, các biến cục bộ, biến mẫu và biến toàn cầu đều hoạt động giống nhau.
có các lý do khác & hellip; các biến lớp không thể hoạt động như vậy?
Tôi không biết. Ví dụ, biến rất tiện lợi, vì không giống như Java, ví dụ, trong đó các biến mẫu được khai báo trong định nghĩa lớp und do đó luôn luôn tồn tại cho mọi cá thể của lớp, trong Ruby, các biến mẫu không được khai báo ở bất kỳ đâu. Họ chỉ kỳ diệu mọc vào sự tồn tại, ngay sau khi họ được phân công. Vì các biến mẫu không nhất thiết được đảm bảo tồn tại, các phương thức viết sử dụng các biến mẫu sẽ là một nỗi đau nếu chúng ném các ngoại lệ.
Tại sao các biến phân cấp lớp khác nhau, tôi không có ý tưởng. Có lẽ bởi vì không ai sử dụng chúng dù sao, hoặc vì chúng thường có xu hướng được khởi tạo trong phần thân của lớp và đơn giản là không được truy cập khi chúng không được khởi tạo.