Menu
CoddyTech

Ö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; nesnenin yalnızca bu yönteme sahip olması yeterlidir. "Ördek gibi yürüyüp ördek gibi vaklıyorsa, o bir ördektir." Bu, ördek tiplemesidir: ortak bir üst sınıfı olmayan sınıflar yine de 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 buna katılır. Yalnızca << kullanan bir yöntem; bir diziyle, bir metin dizisiyle 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 genel erişimli bir yönteme sahip olup olmadığını sorar. Bir nesnenin isteğe bağlı bir özelliği destekleyip desteklemeyebileceği durumlarda bunu 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

Nesnede yöntem yoksa çağrı, yöntem ile nesnenin adını veren bir iletiye sahip olan NoMethodError hatasını oluşturur. Ördek tiplemesi, kendisine geçirilen her nesnenin gönderilen yöntemleri yanıtlayabilmesine 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

Tamamlayıcı sınıflar olan Printer ve LineCounter ile yardımcı export(items, target) işlevini functions.rb içinde tamamla. export, her öğeyi target << item.to_s ile hedefe gönderir ve hedefi döndürür. Printer#<<, metni satır numarasıyla birlikte 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 ve bunları bir diziye (p ile yazdırılır), yeni bir dizeye (p ile yazdırılır), bir Printer nesnesine ve bir LineCounter nesnesine (puts ile yazdırılır) aktarır.

Kodun printer.rb, line_counter.rb ve functions.rb dosyalarına yazılı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