Duck Typing
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 33 dari 57.
Ruby tidak memeriksa class suatu object sebelum memanggil method; object hanya perlu memiliki method tersebut. "Jika ia berjalan seperti bebek dan berkwek seperti bebek, berarti ia bebek." Inilah duck typing: class yang tidak memiliki superclass yang sama tetap dapat digunakan di tempat yang sama:
class Duck
def speak
"Quack"
end
end
class Robot
def speak
"Beep"
end
end
class Radio
def speak
"...news..."
end
end
[Duck.new, Robot.new, Radio.new].each { |thing| puts thing.speak }Output:
Quack
Beep
...news...Class bawaan juga ikut berperan. Sebuah method yang hanya menggunakan << dapat bekerja dengan array, string, atau object apa pun milikmu yang mendefinisikan <<:
class Tally
attr_reader :count
def initialize
@count = 0
end
def <<(_item)
@count += 1
self
end
end
def export(items, target)
items.each { |item| target << item.to_s }
target
end
p export([1, 2], [])
p export([1, 2], +"")
puts export([1, 2, 3], Tally.new).countOutput:
["1", "2"]
"12"
3respond_to?(:name) menanyakan apakah sebuah object memiliki method publik, tanpa memanggilnya. Gunakan ini saat sebuah object mungkin mendukung fitur opsional atau tidak:
class Printer
def print_page(text)
"printing #{text}"
end
end
class Scanner
end
[Printer.new, Scanner.new].each do |device|
if device.respond_to?(:print_page)
puts device.print_page("report")
else
puts "#{device.class} cannot print"
end
endOutput:
printing report
Scanner cannot printJika object tidak memiliki method tersebut, pemanggilan akan memunculkan NoMethodError, yang pesannya menyebutkan nama method dan object. Duck typing mengandalkan setiap object yang diteruskan untuk merespons method yang dikirimkan kepadanya:
def loudest(things)
things.map(&:speak).max_by(&:size)
end
class Cat
def speak
"Meow"
end
end
puts loudest([Cat.new, Cat.new])
begin
loudest([Cat.new, 42])
rescue NoMethodError => e
puts e.message
endKeluaran:
Meow
undefined method `speak' for an instance of IntegerTantangan
MudahLengkapi class Printer dan LineCounter, serta fungsi pembantu export(items, target) di functions.rb. export mengirim setiap item ke target dengan target << item.to_s dan mengembalikan target. Printer#<< menampilkan teks dengan nomor baris, 1: text, lalu mengembalikan printer. LineCounter#<< menghitung baris dan karakter, lalu mengembalikan penghitung; to_s mengembalikan 3 lines, 12 chars.
Kode yang disediakan membaca item, lalu mengekspornya ke array (ditampilkan dengan p), ke string baru (ditampilkan dengan p), ke Printer, dan ke LineCounter (ditampilkan dengan puts).
Tempatkan kodemu di printer.rb, line_counter.rb, dan functions.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
require_relative 'printer'
require_relative 'line_counter'
require_relative 'functions'
# Kode input/output yang disediakan: biarkan apa adanya
input = []
while (line = gets)
input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1class dan object
Bekerja dengan fileMendefinisikan classVariabel instansmethod dan selfto_s dan inspectRingkasan: Kartu Perpustakaan4Enkapsulasi
private methodprotected methodprivate setterMelindungi StatusUlasan, Mesin Penjual Otomatis7Polimorfisme dan Duck Typing
PolimorfismeDuck TypingMethod Abstrakcase dan classRingkasan: Method Pembayaran2Accessor dan self
Pembaca dan PenulisSetter Kustomself dalam methodIdentitas dan KesetaraanRangkuman: Daftar Kontak8Special method
Kesetaraan dan hashOperator methodPengindeksan dan penambahanKoleksi kustomRingkasan: Pecahan11Proyek: Manajemen Perpustakaan
Buku dan AnggotaMeminjam Buku3Method dan Variabel class
Method classVariabel instance classKonstantaMethod pabrikRangkuman: Kode KuponLatihan sendiri: Compiler Ruby online