Câu trả lời:
Sử dụng defined?
từ khóa ( tài liệu ). Nó sẽ trả về một Chuỗi với loại vật phẩm hoặc nil
nếu nó không tồn tại.
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
Như skalee nhận xét: "Điều đáng chú ý là biến được đặt thành nil được khởi tạo."
>> n = nil
>> defined? n
=> "local-variable"
||=
toán tử) bên dưới.
defined?
vẫn trả về true cho một biến được xác định trong khối đó!
defined?
trả về boolean?
!!defined?(object_name)
Điều này hữu ích nếu bạn không muốn làm gì nếu nó tồn tại nhưng tạo ra nó nếu nó không tồn tại.
def get_var
@var ||= SomeClass.new()
end
Điều này chỉ tạo ra trường hợp mới một lần. Sau đó, nó tiếp tục trả về var.
||=
với các giá trị boolean, kẻo bạn cảm thấy đau đớn của sự nhầm lẫn.
nil
trừ khi bạn thực sự muốn đánh giá biểu thức mỗi khi nó được gọi khi nó trở lạinil
var = (var or var.nil?)
Cú pháp đúng cho câu lệnh trên là:
if (defined?(var)).nil? # will now return true or false
print "var is not defined\n".color(:red)
else
print "var is defined\n".color(:green)
end
thay thế ( var
) bằng biến của bạn. Cú pháp này sẽ trả về giá trị đúng / sai để đánh giá trong câu lệnh if.
defined?(var) == nil
?
.nil?
là thành ngữ hơn, như họ nói. Đó là "hướng đối tượng" nhiều hơn để hỏi một đối tượng nếu nó nil
hơn là sử dụng một toán tử so sánh. Không khó đọc, vì vậy hãy sử dụng cái nào giúp bạn vận chuyển nhiều sản phẩm hơn.
defined?(your_var)
sẽ làm việc. Tùy thuộc vào những gì bạn đang làm, bạn cũng có thể làm một cái gì đó nhưyour_var.nil?
your_var.nil?
vì nó trả về true của false và đọc và viết tốt hơn nhiều defined? var
. Cám ơn vì cái này.
your_var.nil?
sẽ dẫn đến lỗi: undefined local variable or method your_var
khi không được xác định trước ...
Hãy thử "trừ khi" thay vì "nếu"
a = "apple"
# Note that b is not declared
c = nil
unless defined? a
puts "a is not defined"
end
unless defined? b
puts "b is not defined"
end
unless defined? c
puts "c is not defined"
end
Đây là một số mã, không có gì khoa học tên lửa nhưng nó hoạt động đủ tốt
require 'rubygems'
require 'rainbow'
if defined?(var).nil? # .nil? is optional but might make for clearer intent.
print "var is not defined\n".color(:red)
else
print "car is defined\n".color(:green)
end
Rõ ràng, mã màu là không cần thiết, chỉ là một hình ảnh đẹp trong ví dụ đồ chơi này.
nil?
là tùy chọn.
Đây là câu trả lời chính: defined?
phương pháp. Câu trả lời được chấp nhận ở trên minh họa điều này một cách hoàn hảo.
Nhưng có một con cá mập, ẩn mình dưới những con sóng ...
Xem xét loại mô hình ruby phổ biến này:
def method1
@x ||= method2
end
def method2
nil
end
method2
luôn luôn trở về nil
. Lần đầu tiên bạn gọi method1
, @x
biến không được đặt - do đó method2
sẽ được chạy. và method2
sẽ đặt @x
thành nil
. Điều đó là tốt, và tất cả tốt và tốt. Nhưng điều gì xảy ra lần thứ hai bạn gọi method1
?
Hãy nhớ @x đã được đặt thành nil. But method2
vẫn sẽ được chạy lại !! Nếu phương thức 2 là một công việc tốn kém thì đây có thể không phải là điều bạn muốn.
Hãy để defined?
phương pháp đến giải cứu - với giải pháp này, trường hợp cụ thể đó được xử lý - sử dụng như sau:
def method1
return @x if defined? @x
@x = method2
end
Ma quỷ nằm trong các chi tiết: nhưng bạn có thể trốn tránh con cá mập ẩn nấp đó bằng defined?
phương pháp.
Bạn co thể thử:
unless defined?(var)
#ruby code goes here
end
=> true
Bởi vì nó trả về một boolean.
SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
unless
tuyên bố dường như quá phức tạp
Như nhiều ví dụ khác cho thấy bạn không thực sự cần một boolean từ một phương thức để đưa ra các lựa chọn hợp lý trong ruby. Nó sẽ là một hình thức nghèo nàn để ép buộc mọi thứ đối với một boolean trừ khi bạn thực sự cần một boolean.
Nhưng nếu bạn thực sự cần một boolean. Sử dụng !! (bang bang) hoặc "falsy falsy tiết lộ sự thật".
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
Tại sao nó thường không trả tiền để ép buộc:
>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true
Đây là một ví dụ mà nó quan trọng bởi vì nó dựa vào sự ép buộc ngầm định của giá trị boolean đối với biểu diễn chuỗi của nó.
>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
Cần đề cập rằng việc sử dụng defined
để kiểm tra xem một trường cụ thể được đặt trong hàm băm có thể hoạt động không mong muốn:
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
Cú pháp đúng ở đây, nhưng defined? var['unknown']
sẽ được đánh giá theo chuỗi "method"
, vì vậyif
khối sẽ được thực thi
chỉnh sửa: Ký hiệu chính xác để kiểm tra xem khóa có tồn tại trong hàm băm không:
if var.key?('unknown')
Xin lưu ý phân biệt giữa "được xác định" và "được chỉ định".
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x được định nghĩa ngay cả khi nó không bao giờ được gán!
NameError Exception: undefined local variable or method
và bối rối khi chỉ định / đề cập đến biến duy nhất là trong một khối nếu không bị tấn công.
Ngoài ra, bạn có thể kiểm tra xem nó có được xác định khi ở trong chuỗi thông qua phép nội suy hay không, nếu bạn viết mã:
puts "Is array1 defined and what type is it? #{defined?(@array1)}"
Hệ thống sẽ cho bạn biết loại nếu nó được xác định. Nếu nó không được xác định, nó sẽ chỉ trả về một cảnh báo cho biết biến không được khởi tạo.
Hi vọng điêu nay co ich! :)
defined?
là tuyệt vời, nhưng nếu bạn ở trong môi trường Rails, bạn cũng có thể sử dụng try
, đặc biệt trong trường hợp bạn muốn kiểm tra tên biến động:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil
nil
được khởi tạo.