Menu
Coddy logo textTech

Ördek Tiplemesi

Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 33 / 57.

Ruby, bir yöntemi çağırmadan önce nesnenin sınıfını kontrol etmez; yalnızca nesnenin bu yönteme sahip olması gerekir. "Ördek gibi yürüyorsa ve ördek gibi vaklıyorsa, ördektir." Buna ördek tiplemesi denir: ortak bir üst sınıfı olmayan sınıflar bile aynı yerde kullanılabilir:

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 }

Çıktı:

Quack
Beep
...news...

Yerleşik sınıflar da işin içindedir. Yalnızca << kullanan bir yöntem, bir diziyle, bir dizeyle veya << tanımlayan kendi nesnelerinizden herhangi biriyle çalışır:

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).count

Çıktı:

["1", "2"]
"12"
3

respond_to?(:name), bir nesnenin onu çağırmadan herkese açık bir yönteme sahip olup olmadığını sorar. Bir nesnenin isteğe bağlı bir özelliği destekleyip desteklemeyebileceği durumlarda kullanın:

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
end

Çıktı:

printing report
Scanner cannot print

Nesne bu metoda sahip olmadığında, çağrı NoMethodError hatasını yükseltir; bu hatanın mesajı yöntemin ve nesnenin adını belirtir. Ördek tiplemesi, kendisine gönderilen yöntemleri yanıtlayabilen her nesnenin geçirilmesine dayanır:

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
end

Çıktı:

Meow
undefined method `speak' for an instance of Integer
challenge icon

Görev

Kolay

Printer ve LineCounter sınıflarını ve functions.rb içindeki export(items, target) yardımcı işlevini tamamla. export, her öğeyi target << item.to_s ile hedefe gönderir ve hedefi döndürür. Printer#<<, metni satır numarasıyla, 1: text biçiminde yazdırır ve yazıcıyı döndürür. LineCounter#<<, satırları ve karakterleri sayar ve sayacı döndürür; to_s ise 3 lines, 12 chars döndürür.

Sağlanan kod öğeleri okur, bunları bir diziye (p ile yazdırılır), yeni bir dizeye (p ile yazdırılır), bir Printer'a ve bir LineCounter'a (puts ile yazdırılır) aktarır.

Kodun printer.rb, line_counter.rb ve functions.rb dosyalarına yazılmalıdır. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

require_relative 'printer'
require_relative 'line_counter'
require_relative 'functions'

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
  input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Ruby derleyicisi