Menu
Coddy logo textTech

덕 타이핑

Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 33번째.

Ruby는 메서드를 호출하기 전에 객체의 클래스를 확인하지 않습니다. 객체에 해당 메서드가 있기만 하면 됩니다. "오리처럼 걷고 오리처럼 꽥꽥거리면, 그것은 오리입니다." 이것이 덕 타이핑입니다. 공통 슈퍼클래스를 전혀 공유하지 않는 클래스들도 같은 위치에서 사용할 수 있습니다:

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 }

출력:

Quack
Beep
...news...

내장 클래스도 함께 참여합니다. <<만 사용하는 메서드는 배열, 문자열 또는 <<를 정의한 여러분의 어떤 객체와도 작동합니다:

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

출력:

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

respond_to?(:name)은 객체를 호출하지 않고 객체에 공개 메서드가 있는지 묻습니다. 객체가 선택적 기능을 지원할 수도 있고 지원하지 않을 수도 있을 때 사용하세요:

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

출력:

printing report
Scanner cannot print

객체에 해당 메서드가 없으면 호출 시 NoMethodError가 발생하며, 그 메시지에는 메서드와 객체의 이름이 표시됩니다. 덕 타이핑은 전달된 모든 객체가 자신에게 전송된 메서드에 응답한다는 점에 의존합니다:

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

출력:

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

챌린지

쉬움

Printer 및 LineCounter 클래스와 functions.rb의 헬퍼 export(items, target)를 완성하세요. export는 target << item.to_s를 사용하여 모든 항목을 대상에 보내고 대상을 반환합니다. Printer#<<는 줄 번호와 함께 1: text 형식으로 텍스트를 출력하고 프린터를 반환합니다. LineCounter#<<는 줄 수와 문자 수를 세고 카운터를 반환하며, 해당 to_s는 3 lines, 12 chars를 반환합니다.

제공된 코드는 항목을 읽어 배열로 내보내고(p로 출력), 새 문자열로 내보내며(p로 출력), Printer와 LineCounter로 내보냅니다(puts로 출력).

코드는 printer.rb, line_counter.rb 및 functions.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.

직접 해보기

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

# 제공된 입력/출력 코드: 그대로 유지하세요
input = []
while (line = gets)
  input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Ruby 컴파일러