ฉันจะตรวจสอบว่าตัวแปรถูกกำหนดใน Ruby ได้อย่างไร? มีisset
วิธีการชนิดที่มีอยู่?
ฉันจะตรวจสอบว่าตัวแปรถูกกำหนดใน Ruby ได้อย่างไร? มีisset
วิธีการชนิดที่มีอยู่?
คำตอบ:
ใช้defined?
คำสำคัญ ( เอกสาร ) มันจะส่งคืนสตริงที่มีชนิดของรายการหรือnil
หากไม่มีอยู่
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
ในฐานะที่เป็น skalee แสดงความคิดเห็น: "มันเป็นมูลค่า noting ตัวแปรที่กำหนดให้เป็นศูนย์จะเริ่มต้น"
>> n = nil
>> defined? n
=> "local-variable"
||=
ผู้ดำเนินการ) ด้านล่าง
defined?
ยังคงส่งกลับค่าจริงสำหรับตัวแปรที่กำหนดภายในบล็อกนั้น!
defined?
ที่ส่งกลับบูลีนหรือไม่?
!!defined?(object_name)
สิ่งนี้มีประโยชน์หากคุณไม่ต้องการทำอะไรถ้ามันมีอยู่ แต่สร้างมันขึ้นมาหากไม่มีอยู่
def get_var
@var ||= SomeClass.new()
end
สิ่งนี้จะสร้างอินสแตนซ์ใหม่เพียงครั้งเดียว หลังจากนั้นก็แค่คืนค่า var
||=
กับค่าบูลีนเกรงว่าคุณจะรู้สึกเจ็บปวด
nil
เช่นกันเว้นแต่คุณจะต้องการประเมินการแสดงออกทุกครั้งที่มีการเรียกเมื่อกลับมาnil
var = (var or var.nil?)
ไวยากรณ์ที่ถูกต้องสำหรับคำสั่งข้างต้นคือ:
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
การแทนที่ ( var
) ด้วยตัวแปรของคุณ ไวยากรณ์นี้จะส่งคืนค่าจริง / เท็จสำหรับการประเมินผลในคำสั่ง if
defined?(var) == nil
ล่ะ
.nil?
เป็นสำนวนที่มากขึ้นตามที่พวกเขาพูด มันยิ่ง "เชิงวัตถุ" เพื่อถามวัตถุว่ามันnil
จะใช้ตัวดำเนินการเปรียบเทียบ ไม่สามารถอ่านได้ยากดังนั้นให้ใช้วิธีใดก็ตามที่ช่วยคุณจัดส่งผลิตภัณฑ์ได้มากขึ้น
defined?(your_var)
จะทำงาน. ขึ้นอยู่กับสิ่งที่คุณทำคุณสามารถทำสิ่งที่ชอบyour_var.nil?
your_var.nil?
defined? var
ขอบคุณสำหรับสิ่งนี้.
your_var.nil?
จะส่งผลให้เกิดข้อผิดพลาด: undefined local variable or method your_var
เมื่อไม่ได้กำหนดก่อน ...
ลองใช้ "เว้นแต่" แทน "ถ้า"
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
ใช้defined? YourVariable
ทำให้มันง่ายงี่เง่า .. ;)
นี่คือโค้ดบางส่วนไม่มีวิทยาศาสตร์จรวด แต่ทำงานได้ดีพอ
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
เห็นได้ชัดว่าไม่จำเป็นต้องใช้รหัสระบายสีเพียงแสดงภาพให้ดีในตัวอย่างของเล่นนี้
nil?
มันเป็นตัวเลือก
นี่คือคำตอบที่สำคัญ: defined?
วิธีการ คำตอบที่ได้รับการยอมรับข้างต้นแสดงให้เห็นอย่างสมบูรณ์แบบนี้
แต่มีฉลามซ่อนตัวอยู่ใต้คลื่น ...
ลองพิจารณารูปแบบทับทิมสามัญประเภทนี้:
def method1
@x ||= method2
end
def method2
nil
end
method2
nil
ผลตอบแทนเสมอ ครั้งแรกที่คุณโทรหาmethod1
ที่@x
ตัวแปรไม่ได้ตั้งค่า - จึงmethod2
จะทำงาน และmethod2
จะตั้งไป@x
nil
นั่นเป็นสิ่งที่ดีและทุกอย่างดีและดี แต่จะเกิดอะไรขึ้นในครั้งที่สองที่คุณโทรmethod1
?
จำไว้ว่า @x ถูกตั้งค่าเป็นศูนย์แล้ว But method2
จะยังคงทำงานอีกครั้ง !! หาก method2 เป็นการทำที่มีค่าใช้จ่ายสูงอาจไม่ใช่สิ่งที่คุณต้องการ
ให้defined?
วิธีมาช่วยเหลือ - ด้วยวิธีแก้ปัญหานี้กรณีนั้นได้รับการจัดการ - ใช้สิ่งต่อไปนี้:
def method1
return @x if defined? @x
@x = method2
end
มารอยู่ในรายละเอียด: แต่คุณสามารถหลบเลี่ยงฉลามที่ซุ่มซ่อนด้วยdefined?
วิธีการ
คุณสามารถลอง:
unless defined?(var)
#ruby code goes here
end
=> true
เพราะมันส่งคืนบูลีน
SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
unless
คำสั่งดูซับซ้อนเกินไป
ตัวอย่างอื่น ๆ แสดงให้เห็นว่าคุณไม่จำเป็นต้องใช้บูลีนจากวิธีการเลือกตรรกะในทับทิม มันจะเป็นรูปแบบที่ไม่ดีในการบีบบังคับทุกอย่างให้กับบูลีนเว้นแต่ว่าคุณต้องการบูลีนจริงๆ
แต่ถ้าคุณต้องการบูลีนจริงๆ ใช้ !! (bang bang) หรือ "falsy falsy เปิดเผยความจริง"
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
ทำไมมันมักจะไม่จ่ายเงินเพื่อบีบบังคับ:
>> (!!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
นี่คือตัวอย่างที่สำคัญเพราะขึ้นอยู่กับการบีบบังคับค่าบูลีนโดยนัยของการแทนค่าสตริง
>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
ควรกล่าวว่าการใช้defined
เพื่อตรวจสอบว่ามีการตั้งค่าฟิลด์เฉพาะในแฮชอาจทำงานผิดปกติหรือไม่:
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
ไวยากรณ์ถูกต้องที่นี่ แต่defined? var['unknown']
จะถูกประเมินเป็นสตริง"method"
ดังนั้นif
บล็อกจะถูกดำเนินการ
แก้ไข: สัญกรณ์ที่ถูกต้องสำหรับการตรวจสอบว่ามีกุญแจอยู่ในแฮชหรือไม่:
if var.key?('unknown')
โปรดทราบความแตกต่างระหว่าง "กำหนด" และ "กำหนด"
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x ถูกกำหนดแม้ว่าจะไม่เคยกำหนด!
NameError Exception: undefined local variable or method
และสับสนเมื่อมีการมอบหมาย / เอ่ยถึงตัวแปรในบล็อกที่ไม่ได้รับการตี
นอกจากนี้คุณสามารถตรวจสอบว่ามันถูกกำหนดในขณะที่อยู่ในสตริงผ่านการแก้ไขถ้าคุณรหัส:
puts "Is array1 defined and what type is it? #{defined?(@array1)}"
ระบบจะแจ้งให้คุณทราบประเภทหากมีการกำหนดไว้ ถ้ามันไม่ได้ถูกกำหนดมันก็จะส่งกลับคำเตือนว่าตัวแปรไม่ได้เริ่มต้น
หวังว่านี่จะช่วยได้! :)
defined?
ดีมาก แต่ถ้าคุณอยู่ในสภาพแวดล้อมของ Rails คุณสามารถใช้งานtry
ได้โดยเฉพาะในกรณีที่คุณต้องการตรวจสอบชื่อตัวแปรแบบไดนามิก:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil
nil
ถูกเตรียมใช้งาน