Saya baru saja membaca artikel blog dan memperhatikan bahwa penulis menggunakan tap
potongan seperti:
user = User.new.tap do |u|
u.username = "foobar"
u.save!
end
Pertanyaan saya sebenarnya apa sih manfaat atau keuntungan menggunakan tap
? Tidak bisakah saya melakukan:
user = User.new
user.username = "foobar"
user.save!
atau lebih baik lagi:
user = User.create! username: "foobar"
User.new.tap &:foobar
user = User.create!(username: 'foobar')
akan menjadi yang paling jelas dan terpendek dalam kasus ini :) - contoh terakhir dari pertanyaan tersebut.user
." Juga, argumen bahwa "Seorang pembaca tidak perlu membaca apa yang ada di dalam blok untuk mengetahui bahwa sebuah instanceuser
dibuat." tidak memiliki bobot, karena di blok kode pertama, pembaca juga hanya perlu membaca baris pertama "untuk mengetahui bahwa sebuah instanceuser
dibuat".Kasus lain menggunakan tap adalah melakukan manipulasi pada objek sebelum mengembalikannya.
Jadi, alih-alih ini:
kami dapat menghemat baris tambahan:
Dalam beberapa situasi, teknik ini dapat menghemat lebih dari satu baris dan membuat kode lebih kompak.
sumber
some_object.tap(&:serialize)
Menggunakan tap, seperti yang dilakukan blogger, hanyalah metode kenyamanan. Ini mungkin berlebihan dalam contoh Anda, tetapi dalam kasus di mana Anda ingin melakukan banyak hal dengan pengguna, tap bisa dibilang menyediakan antarmuka yang tampak lebih bersih. Jadi, mungkin lebih baik dalam contoh sebagai berikut:
Menggunakan cara di atas memudahkan untuk melihat dengan cepat bahwa semua metode tersebut dikelompokkan bersama sehingga semuanya merujuk ke objek yang sama (pengguna dalam contoh ini). Alternatifnya adalah:
Sekali lagi, ini masih bisa diperdebatkan - tetapi kasusnya dapat dibuat bahwa versi kedua terlihat sedikit lebih berantakan, dan membutuhkan sedikit lebih banyak penguraian manusia untuk melihat bahwa semua metode dipanggil pada objek yang sama.
sumber
user = User.new, user.do_something, user.do_another_thing
... bisakah Anda menjelaskan mengapa orang melakukan ini?tap
tidak pernah menambahkan manfaat apa pun dalam pengalaman saya. Membuat, dan bekerja dengan,user
variabel lokal jauh lebih bersih, dan dapat dibaca menurut saya.u = user = User.new
dan kemudian digunakanu
untuk panggilan pengaturan, itu akan lebih sesuai dengan contoh pertama.Ini bisa berguna dengan men - debug serangkaian
ActiveRecord
cakupan yang dirantai.Ini membuatnya sangat mudah untuk men-debug di titik mana pun dalam rantai tanpa harus menyimpan apa pun di variabel lokal atau memerlukan banyak perubahan pada kode asli.
Dan terakhir, gunakan sebagai cara cepat dan tidak mengganggu untuk men-debug tanpa mengganggu eksekusi kode normal :
sumber
Visualisasikan contoh Anda dalam suatu fungsi
Ada risiko pemeliharaan yang besar dengan pendekatan itu, pada dasarnya nilai pengembalian implisit .
Dalam kode itu, Anda bergantung pada
save!
mengembalikan pengguna yang disimpan. Tetapi jika Anda menggunakan bebek yang berbeda (atau bebek Anda saat ini berkembang), Anda mungkin mendapatkan hal-hal lain seperti laporan status penyelesaian. Oleh karena itu, perubahan pada bebek mungkin merusak kode, sesuatu yang tidak akan terjadi jika Anda memastikan nilai pengembalian denganuser
ketukan biasa atau gunakan.Saya telah sering melihat kecelakaan seperti ini, khususnya dengan fungsi di mana nilai pengembalian biasanya tidak digunakan kecuali untuk satu sudut kereta gelap.
Nilai pengembalian implisit cenderung menjadi salah satu hal di mana pemula cenderung merusak hal-hal dengan menambahkan kode baru setelah baris terakhir tanpa memperhatikan efeknya. Mereka tidak melihat arti sebenarnya dari kode di atas:
sumber
user
?User.new.tap{ |u| u.username = name; u.save! }
Jika Anda ingin mengembalikan pengguna setelah menyetel nama pengguna, Anda harus melakukannya
Dengan
tap
Anda bisa menyelamatkan pengembalian canggung itusumber
Object#tap
bagi saya.user = User.new.tap {|u| u.username = 'foobar' }
Ini menghasilkan kode yang tidak terlalu berantakan karena ruang lingkup variabel terbatas hanya pada bagian yang benar-benar dibutuhkan. Selain itu, lekukan di dalam blok membuat kode lebih mudah dibaca dengan menyatukan kode yang relevan.
Deskripsi
tap
kata :Jika kita mencari kode sumber rails untuk
tap
digunakan , kita dapat menemukan beberapa penggunaan yang menarik. Di bawah ini adalah beberapa item (bukan daftar lengkap) yang akan memberi kita sedikit ide tentang cara menggunakannya:Menambahkan elemen ke larik berdasarkan kondisi tertentu
Menginisialisasi sebuah array dan mengembalikannya
Sebagai gula sintaksis untuk membuat kode lebih mudah dibaca - Dapat dikatakan, dalam contoh di bawah ini, penggunaan variabel
hash
danserver
membuat maksud kode lebih jelas.Inisialisasi / panggil metode pada objek yang baru dibuat.
Di bawah ini adalah contoh dari file tes
Untuk bertindak atas hasil
yield
panggilan tanpa harus menggunakan variabel sementara.sumber
Variasi dari jawaban @ sawa:
Seperti yang telah disebutkan, penggunaan
tap
membantu mencari tahu maksud kode Anda (meski tidak selalu membuatnya lebih ringkas).Dua fungsi berikut sama panjangnya, tetapi yang pertama Anda harus membaca sampai akhir untuk mencari tahu mengapa saya menginisialisasi Hash kosong di awal.
Di sini, di sisi lain, Anda tahu sejak awal bahwa hash yang diinisialisasi akan menjadi keluaran blok (dan, dalam hal ini, nilai kembalian fungsi).
sumber
tap
menghasilkan argumen yang lebih menarik. Saya setuju dengan orang lain bahwa ketika Anda melihatuser = User.new
, maksudnya sudah jelas. Struktur data anonim, bagaimanapun, dapat digunakan untuk apa saja, dantap
metode setidaknya menjelaskan bahwa struktur data adalah fokus dari metode tersebut.def tapping1; {one: 1, two: 2}; end
acara.tap
sekitar 50% lebih lambat dalam kasus iniIni adalah penolong untuk rantai panggilan. Ini melewati objeknya ke dalam blok yang diberikan dan, setelah blok selesai, mengembalikan objek:
Manfaatnya adalah ketukan selalu mengembalikan objek yang dipanggil, bahkan jika blok mengembalikan beberapa hasil lain. Dengan demikian, Anda dapat memasukkan blok keran ke tengah jalur pipa metode yang ada tanpa merusak aliran.
sumber
Saya akan mengatakan bahwa tidak ada keuntungan menggunakan
tap
. Satu-satunya manfaat potensial, seperti yang ditunjukkan @sawa adalah, dan saya mengutip: "Seorang pembaca tidak perlu membaca apa yang ada di dalam blok untuk mengetahui bahwa pengguna instance dibuat." Namun, pada saat itu argumen dapat dibuat bahwa jika Anda melakukan logika pembuatan rekaman non-simplistik, maksud Anda akan lebih baik dikomunikasikan dengan mengekstrak logika itu ke dalam metodenya sendiri.Saya berpegang pada pendapat bahwa
tap
beban yang tidak perlu pada pembacaan kode, dan dapat dilakukan tanpa, atau diganti dengan teknik yang lebih baik, seperti Metode Ekstrak .Meskipun
tap
merupakan metode kenyamanan, ini juga merupakan preferensi pribadi. Berikantap
mencoba. Kemudian tulis beberapa kode tanpa menggunakan tap, lihat apakah Anda menyukai satu cara di atas yang lain.sumber
Mungkin ada sejumlah kegunaan dan tempat di mana kami dapat menggunakannya
tap
. Sejauh ini saya hanya menemukan 2 penggunaan berikuttap
.1) Tujuan utama dari metode ini adalah untuk memanfaatkan rantai metode, untuk melakukan operasi pada hasil antara dalam rantai tersebut. yaitu
2) Apakah Anda pernah menemukan diri Anda memanggil metode pada beberapa objek, dan nilai kembaliannya tidak seperti yang Anda inginkan? Mungkin Anda ingin menambahkan nilai arbitrer ke sekumpulan parameter yang disimpan dalam hash. Anda memperbaruinya dengan Hash. [] , Tetapi Anda mendapatkan bilah belakang alih-alih hash params, jadi Anda harus mengembalikannya secara eksplisit. yaitu
Untuk mengatasi situasi ini di sini,
tap
metode ikut bermain. Sebut saja pada objek, lalu lewati tap blok dengan kode yang ingin Anda jalankan. Objek tersebut akan diserahkan ke blok tersebut, kemudian dikembalikan. yaituAda lusinan kasus penggunaan lainnya, coba temukan sendiri :)
Sumber:
1) API Dock Object tap
2) lima-ruby-metode-Anda-harus-menggunakan
sumber
Anda benar: penggunaan
tap
dalam contoh Anda tidak ada gunanya dan mungkin kurang bersih daripada alternatif Anda.Sebagai catatan Rebitzele,
tap
hanyalah metode kenyamanan, sering digunakan untuk membuat referensi yang lebih pendek ke objek saat ini.Salah satu kasus penggunaan yang baik
tap
adalah untuk debugging: Anda dapat memodifikasi objek, mencetak status saat ini, lalu melanjutkan memodifikasi objek di blok yang sama. Lihat di sini misalnya: http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions .Saya kadang-kadang suka menggunakan
tap
metode di dalam untuk kembali bersyarat lebih awal sambil mengembalikan objek saat ini sebaliknya.sumber
Ada alat yang disebut flog yang mengukur seberapa sulit membaca suatu metode. "Semakin tinggi skornya, semakin sulit kode tersebut."
dan menurut hasil cambuk, metode dengan
tap
yang paling sulit dibaca (dan saya setuju dengan itu)sumber
Anda dapat membuat kode Anda lebih modular menggunakan tap, dan dapat mencapai pengelolaan variabel lokal yang lebih baik. Misalnya, dalam kode berikut, Anda tidak perlu menetapkan variabel lokal ke objek yang baru dibuat, dalam lingkup metode. Perhatikan bahwa variabel blok, u , dibatasi di dalam blok. Ini sebenarnya adalah salah satu keindahan kode ruby.
sumber
Di rails kita dapat menggunakan
tap
parameter whitelist secara eksplisit:sumber
Saya akan memberikan contoh lain yang telah saya gunakan. Saya memiliki metode user_params yang mengembalikan params yang diperlukan untuk disimpan untuk pengguna (ini adalah proyek Rails)
Anda dapat melihat saya tidak mengembalikan apa pun kecuali ruby mengembalikan output dari baris terakhir.
Kemudian, setelah beberapa saat, saya perlu menambahkan atribut baru secara kondisional. Jadi, saya mengubahnya menjadi seperti ini:
Di sini kita dapat menggunakan tap untuk menghapus variabel lokal dan menghapus return:
sumber
Di dunia di mana pola pemrograman fungsional menjadi praktik terbaik ( https://maryrosecook.com/blog/post/a-praktis-introduction-to-functional-programming ), Anda dapat melihat
tap
, sebagaimap
satu nilai, memang , untuk mengubah data Anda pada rantai transformasi.Tidak perlu mendeklarasikan
item
berkali-kali di sini.sumber
Apa bedanya?
Perbedaan dalam hal keterbacaan kode adalah gaya belaka.
Kode Berjalan melalui:
Poin utama:
u
variabel sekarang digunakan sebagai parameter blok?user
variabel sekarang harus mengarah ke Pengguna (dengan nama pengguna: 'foobar', dan siapa yang juga disimpan).Dokumentasi API
Berikut adalah versi kode sumber yang mudah dibaca:
Untuk info lebih lanjut, lihat tautan berikut:
https://apidock.com/ruby/Object/tap
http://ruby-doc.org/core-2.2.3/Object.html#method-i-tap
sumber