Bagaimana saya bisa memeriksa apakah suatu variabel didefinisikan dalam Ruby? Apakah ada isset
metode tipe yang tersedia?
Bagaimana saya bisa memeriksa apakah suatu variabel didefinisikan dalam Ruby? Apakah ada isset
metode tipe yang tersedia?
Jawaban:
Gunakan defined?
kata kunci ( dokumentasi ). Ini akan mengembalikan sebuah String dengan jenis item, atau nil
jika tidak ada.
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
Seperti komentar skalee: "Perlu dicatat bahwa variabel yang ditetapkan ke nol diinisialisasi."
>> n = nil
>> defined? n
=> "local-variable"
||=
operator) di bawah ini.
defined?
masih mengembalikan true untuk variabel yang didefinisikan dalam blok itu!
defined?
itu mengembalikan boolean?
!!defined?(object_name)
Ini berguna jika Anda tidak ingin melakukan apa pun jika memang ada, tetapi buat jika itu tidak ada.
def get_var
@var ||= SomeClass.new()
end
Ini hanya membuat instance baru sekali. Setelah itu terus mengembalikan var.
||=
dengan nilai boolean, jangan sampai Anda merasakan sakit kebingungan.
nil
juga, kecuali jika Anda benar - benar ingin mengevaluasi ekspresi setiap kali dipanggil kembalinil
var = (var or var.nil?)
Sintaks yang benar untuk pernyataan di atas adalah:
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
mengganti ( var
) dengan variabel Anda. Sintaks ini akan mengembalikan nilai benar / salah untuk evaluasi dalam pernyataan if.
defined?(var) == nil
?
.nil?
lebih idiomatis, seperti yang mereka katakan. Ini lebih "berorientasi objek" untuk menanyakan objek jika nil
daripada menggunakan operator perbandingan. Tidak ada yang sulit dibaca, jadi gunakan yang mana saja yang membantu Anda mengirimkan lebih banyak produk.
defined?(your_var)
akan bekerja. Bergantung pada apa yang Anda lakukan, Anda juga bisa melakukan sesuatuyour_var.nil?
your_var.nil?
karena mengembalikan true of false dan jauh lebih baik untuk membaca dan menulis daripada defined? var
. Terima kasih untuk ini.
your_var.nil?
akan menghasilkan kesalahan: undefined local variable or method your_var
bila tidak ditentukan sebelumnya ...
Coba "kecuali" daripada "jika"
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
Ini ada beberapa kode, bukan ilmu roket tapi itu bekerja dengan cukup baik
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
Jelas, kode pewarnaan tidak diperlukan, hanya visualisasi yang bagus dalam contoh mainan ini.
nil?
ini opsional.
Ini adalah kunci jawaban: defined?
metode. Jawaban yang diterima di atas menggambarkan hal ini dengan sempurna.
Tapi ada hiu, bersembunyi di bawah ombak ...
Pertimbangkan jenis pola ruby umum ini:
def method1
@x ||= method2
end
def method2
nil
end
method2
selalu kembali nil
. Pertama kali Anda menelepon method1
, @x
variabel tidak disetel - karena itu method2
akan dijalankan. dan method2
akan diatur @x
ke nil
. Itu baik, dan semuanya baik-baik saja. Tapi apa yang terjadi saat Anda menelepon kedua kali method1
?
Ingat @x sudah disetel ke nol. But method2
masih akan berjalan lagi !! Jika method2 adalah usaha mahal, ini mungkin bukan sesuatu yang Anda inginkan.
Biarkan defined?
metode datang ke penyelamatan - dengan solusi ini, kasus tertentu ditangani - gunakan yang berikut:
def method1
return @x if defined? @x
@x = method2
end
Iblis ada dalam rinciannya: tetapi Anda dapat menghindari hiu yang mengintai itu dengan defined?
metode itu.
Anda dapat mencoba:
unless defined?(var)
#ruby code goes here
end
=> true
Karena mengembalikan boolean.
SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
unless
pernyataan tampaknya terlalu rumit
Seperti banyak contoh lain menunjukkan Anda tidak benar-benar membutuhkan boolean dari suatu metode untuk membuat pilihan logis dalam ruby. Ini akan menjadi bentuk yang buruk untuk memaksa semuanya ke boolean kecuali Anda benar-benar membutuhkan boolean.
Tetapi jika Anda benar-benar membutuhkan boolean. Gunakan !! (bang bang) atau "falsy falsy mengungkapkan kebenaran".
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
Mengapa biasanya tidak membayar untuk memaksa:
>> (!!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
Berikut adalah contoh di mana itu penting karena bergantung pada paksaan implisit dari nilai boolean untuk representasi stringnya.
>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
Harus disebutkan bahwa menggunakan defined
untuk memeriksa apakah bidang tertentu diatur dalam hash mungkin berperilaku tak terduga:
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
Sintaksnya benar di sini, tetapi defined? var['unknown']
akan dievaluasi ke string "method"
, sehingga if
blok akan dieksekusi
sunting: Notasi yang benar untuk memeriksa apakah kunci ada dalam hash adalah:
if var.key?('unknown')
Harap perhatikan perbedaan antara "terdefinisi" dan "ditugaskan".
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x didefinisikan meskipun tidak pernah ditugaskan!
NameError Exception: undefined local variable or method
, dan bingung ketika satu-satunya penugasan / penyebutan variabel berada di blok if yang tidak terkena.
Selain itu, Anda dapat memeriksa apakah itu didefinisikan dalam string melalui interpolasi, jika Anda kode:
puts "Is array1 defined and what type is it? #{defined?(@array1)}"
Sistem akan memberi tahu Anda jenisnya jika sudah ditentukan. Jika tidak didefinisikan, itu hanya akan mengembalikan peringatan yang mengatakan variabel tidak diinisialisasi.
Semoga ini membantu! :)
defined?
bagus, tetapi jika Anda berada di lingkungan Rails Anda juga dapat menggunakan try
, terutama dalam kasus di mana Anda ingin memeriksa nama variabel dinamis:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil
nil
yang diinisialisasi.