Cara memahami nil vs kosong vs kosong di Ruby


1129

Saya menemukan diri saya berulang kali mencari definisi yang jelas tentang perbedaan nil?, blank?dan empty?di Ruby on Rails. Inilah yang paling dekat dengan saya:

  • blank?objek adalah string palsu, kosong, atau spasi. Sebagai contoh, "", " ", nil, [], dan {}kosong.

  • nil? objek adalah instance dari NilClass.

  • empty?objek adalah kelas-spesifik, dan definisi bervariasi dari kelas ke kelas. String kosong jika tidak memiliki karakter, dan array kosong jika tidak mengandung item.

Apakah ada yang hilang, atau perbandingan yang lebih ketat yang bisa dibuat?


26
Satu gotcha adalah array kosong yang mengembalikan false untuk present?. Yang karena blank?mengembalikan true untuk array kosong.
Kris

4
Satu hal yang menyenangkan adalah untuk melihat bahwa :nil?didefinisikan pada ::Kerneldan diganti pada ::NilClass, sementara :empty?diimplementasikan secara terpisah di banyak kelas (native pada ::String, ::Array, ::Hash, dan non-native di kelas-kelas lain seperti ::Setdari stdlib dan ::ActiveRecord::Relationdari rel). Jadi :nil?tersedia di semua subclass ::Objectdan juga di setiap kelas yang termasuk ::Kerneldengan sendirinya, di mana :empty?harus diterapkan atau dimasukkan secara khusus di kelas Anda.
ditulis ulang

Jika Anda mencoba memahami keseluruhan nilkonsep, mulailah dari sini .
totymedli

[1] pry(main)> [].blank? => true
Michael

Jawaban:


1437

.nil? dapat digunakan pada objek apa pun dan benar jika objek tersebut nihil.

.empty? dapat digunakan pada string, array dan hash dan mengembalikan true jika:

  • Panjang string == 0
  • Panjang array == 0
  • Panjang hasht == 0

Menjalankan .empty?sesuatu yang nihil akan melempar NoMethodError.

Di situlah .blank?masuk. Ini diterapkan oleh Rails dan akan beroperasi pada objek apa pun serta bekerja seperti .empty?pada string, array dan hash.

nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
0.blank? == false

.blank? juga mengevaluasi true pada string yang tidak kosong tetapi hanya berisi spasi putih:

"  ".blank? == true
"  ".empty? == false

Rails juga menyediakan .present? , yang mengembalikan negasi .blank?.

Array Gotcha: blank?akan kembali falsebahkan jika semua elemen array kosong. Untuk menentukan kekosongan dalam hal ini, gunakan all?dengan blank?, misalnya:

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 

27
Seperti disebutkan dalam pertanyaan, beberapa string non-kosong dihitung sebagai kosong.
Andrew Grimm

1
Mengapa mereka tidak menimpa. Nihil ini? jika mereka bisa menambahkan .blank?
tillda

6
Juga:false.blank? == true
Shannon

2
Saya akan menyebutkan presence!
Marc-André Lafortune

2
Sebagai tambahan pada gotcha semua-kosong yang disebutkan Tom dalam jawabannya, perlu diketahui bahwa ini dapat menyebabkan masalah keamanan di mana penyerang dapat menggunakan kode tidak siap yang hanya memeriksa kecuali params.nil? atau kecuali params.blank ?, dan apakah penyebab banyak diskusi dan pekerjaan saat ini di Rails. Lihat di sini untuk informasi lebih lanjut: github.com/rails/rails/issues/13420
Houen

675

Saya membuat tabel yang berguna ini dengan semua kasus:

masukkan deskripsi gambar di sini

blank?, present?disediakan oleh Rails.


57
Perlu dicatat bahwa kosong? dan hadir? hanya untuk Kereta Api. Mereka mengembalikan Pengecualian: NoMethodError di Ruby 2.0.0.
Lonny Eachus

17
Pertimbangkan untuk menambahkan any?jika Anda pernah memperbarui tabel.
Dennis

blank?dan present?bukan " Rails-only ", mereka secara otomatis disertakan oleh Rails tetapi dapat dengan mudah dimasukkan dalam kode non-Rails dengan menggunakan ekstensi Core ActiveSupport. Lihat stackoverflow.com/questions/4238867/…
the Tin Man

215

Cukup rentangkan meja Julian:

masukkan deskripsi gambar di sini

Ref: kosong? Kosong? Kosong? 傻傻 分不清楚


1
@ Sibevin Wang, saya telah mengunduh tabel ini dan menggunakannya dalam beberapa jawaban saya menambahkan kredit untuk Anda. Semoga Anda tidak keberatan :) Salam untuk usaha yang luar biasa ini!
Lahiru

1
Enumerable#any?adalah vanilla Ruby, tidak boleh terdaftar di bawah "rails only"
daniero

1
@daniero Terima kasih atas pengingat Anda, tabel diperbarui.
Sibevin Wang

Jenis numerik juga memiliki .zero?dan.nonzero?
DaveMongoose

63

Kiat cepat: !obj.blank? == obj.present?

Dapat berguna / lebih mudah di mata dalam beberapa ekspresi


apakah ada sesuatu yang setara dengan! obj.nil?
Kirk

present?adalah bagian dari active_support, periksa di sini tentang apa yang harus disertakan untuk mendapatkannya: stackoverflow.com/a/4648704/1569
Factor Mystic

2
@Kirk: !! obj sama dengan! Obj.nil?
Mohamed Hafez

4
@MohamedHafez Tidak bukan. !!false
Ajedi32

Agh, @ Ajedi32 tangkapan bagus! setara dengan satu pengecualian itu.
Mohamed Hafez

52

Salah satu perbedaan adalah bahwa .nil?dan .empty?adalah metode yang disediakan oleh bahasa pemrograman Ruby, sedangkan .blank?sesuatu ditambahkan oleh kerangka pengembangan web Rails.


49

masukkan deskripsi gambar di sini

  • Semua yang nil?adablank?
  • Semua yang empty?adablank?
  • Tidak ada yang empty?adalahnil?
  • Tidak ada yang nil?adalahempty?

tl; dr - hanya gunakan blank?& present?kecuali Anda ingin membedakan antara ""dan" "


2
Wow! Anda mendapatkan +1 saya
Am33d

16

Kasus khusus adalah ketika mencoba menilai apakah nilai boolean nol:

false.present? == false
false.blank? == true
false.nil? == false

Dalam hal ini rekomendasi akan digunakan .nil?


14

Hanya sedikit catatan tentang any?rekomendasi: Dia benar bahwa itu umumnya setara dengan !empty?. Namun, any?akan kembali trueke string hanya spasi putih (ala " ").

Dan tentu saja, lihat 1.9 komentar di atas juga.


Di Rails, string apa pun yang berisi karakter spasi kosong adalah "kosong": "\ n \ r \ t" .blank? # => true
Lonny Eachus

13

Jangan lupa any?yang umumnya !empty?. Di Rails saya biasanya memeriksa keberadaan sesuatu di akhir pernyataan dengan if somethingatau unless somethingmenggunakan di blank?mana diperlukan karena tampaknya berfungsi di mana-mana.


4
.apa saja? tidak bekerja dengan string di ruby ​​1.9, seperti .any? membutuhkan enumerable, dan string # masing-masing dengan sendirinya tidak berfungsi di ruby ​​1.9.
Andrew Grimm

4
Berhati-hati any?dalam memeriksa ketidak-kekosongan. Ini mengembalikan false jika Anda memiliki array nilai-nilai palsu. Cara untuk menyiasatinya adalah dengan melewati blok yang selalu benar:, [nil, false].any?{ true }tetapi !empty?lebih pendek dan Anda tidak ingat perilaku anehnya.
Kelvin

12

nil?adalah metode standar Ruby yang dapat dipanggil pada semua objek dan kembali truejika objeknya adalah nil:

b = nil
b.nil? # => true

empty?adalah metode standar Ruby yang dapat dipanggil pada beberapa objek seperti Strings, Array dan Hash dan kembali truejika objek ini tidak mengandung elemen:

a = []
a.empty? # => true

b = ["2","4"]
b.empty? # => false

empty?tidak bisa dipanggil pada nilobjek.

blank?adalah metode Rails yang dapat dipanggil pada nilobjek maupun objek kosong.


7

Semua orang telah menjelaskan dengan baik apa bedanya.

Saya ingin menambahkan di Ruby On Rails, lebih baik menggunakan obj.blank?atau obj.present?daripada obj.nil?atauobj.empty? .

obj.blank?menangani semua jenis nil, '', [], {}, dan kembali truejika nilai-nilai tidak tersedia dan kembali falsejika nilai-nilai yang tersedia pada setiap jenis objek.


5

exists?Metode dapat digunakan untuk memeriksa apakah data ada dalam database atau tidak. Ini mengembalikan nilai boolean baik trueatau false.


Hanya bekerja pada kelas model!
Roger

4

Rel 4

alternatif untuk @ corban-brook 'Array gotcha: blank?' untuk memeriksa apakah array hanya memiliki nilai kosong dan dapat dianggap kosong? benar:

[ nil, '' ].all? &:blank? == true

seseorang juga bisa melakukannya:

[nil, '', "", " ",' '].reject(&:blank?).blank? == true

3

nil?dapat digunakan pada objek apa saja. Ini menentukan apakah objek memiliki nilai atau tidak, termasuk nilai 'kosong'.

Sebagai contoh:

example = nil
example.nil?  # true

"".nil?  # false

Pada dasarnya nil? hanya akan pernah mengembalikan true jika objek tersebut sebenarnya sama dengan 'nil'.

empty?hanya dipanggil pada objek yang dianggap koleksi. Ini termasuk hal-hal seperti string (kumpulan karakter), hash (kumpulan pasangan kunci / nilai) dan array (kumpulan objek yang berubah-ubah). empty?Mengembalikan nilai true adalah tidak ada item dalam koleksi.

Sebagai contoh:

"".empty? # true
"hi".empty?   # false
{}.empty?  # true
{"" => ""}.empty?   # false
[].empty?   # true
[nil].empty?  # false

nil.empty?  # NoMethodError: undefined method `empty?' for nil:NilClass

Perhatikan bahwa empty?tidak dapat dipanggil pada objek nil karena objek nil bukan koleksi dan itu akan menimbulkan pengecualian.

Juga perhatikan bahwa meskipun item dalam koleksi kosong, itu tidak berarti koleksi kosong.

blank?pada dasarnya adalah kombinasi dari nil?dan empty?Ini berguna untuk memeriksa objek yang Anda anggap koleksi, tetapi bisa juga nol.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.