Menu
CoddyTech

Memperluas object

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 28 dari 57.

extend menambahkan method sebuah module ke satu object, bukan ke semua instance. Memperluas class menambahkan method tersebut ke object class, sehingga method itu menjadi method class:

module Describable
  def describe
    "#{name} has #{instance_methods(false).size} methods"
  end
end

class Dog
  extend Describable

  def bark
    "Woof"
  end

  def sit
    "sits"
  end
end

puts Dog.describe

Output:

Dog has 2 methods

Sebuah module yang digunakan dengan extend dapat menyimpan state dalam variabel instance milik class. Setiap class yang memperluasnya mendapatkan salinannya sendiri, sebagai variabel instance class:

module Counted
  def created
    @created ||= 0
  end

  def record
    @created = created + 1
  end
end

class Order
  extend Counted
end

class Invoice
  extend Counted
end

Order.record
Order.record
Invoice.record
puts "#{Order.created} #{Invoice.created}"

Output:

2 1

extend juga berfungsi pada satu object. Hanya object itu yang mendapatkan method, instance lain dari class-nya tetap tidak berubah, dan is_a? bernilai true hanya untuk object yang diperluas:

module Shiny
  def polish
    "#{self} is shining"
  end
end

a = "car"
b = "bike"
a.extend(Shiny)
puts a.polish
puts a.is_a?(Shiny)
puts b.respond_to?(:polish)

Output:

car is shining
true
false

Kedua kata kunci ini menempatkan method dari module yang sama di tempat yang berbeda. include menjadikannya method instance dari sebuah class, sedangkan extend menjadikannya method dari satu object yang diperluas:

class Order
  include Printable    # order.print_me       (setiap instance)
  extend Counted       # Order.record         (class itu sendiri)
end

item.extend(Shiny)     # item.polish          (hanya object ini)
challenge icon

Tantangan

Mudah

Lengkapi module Registry, yang digunakan oleh class dengan extend. register(name) menambahkan nama ke list milik class itu sendiri, yang disimpan di @entries (dibuat saat pertama kali digunakan), lalu mengembalikan Plugin registered x; nama yang sudah ada akan mengembalikan Plugin already has x. entries mengembalikan list dan count mengembalikan ukurannya. Plugin dan Theme sama-sama menggunakan extend pada Registry dan menyimpan list yang terpisah.

Kode yang disediakan membaca baris plugin name atau theme name, memanggil register pada class yang sesuai, lalu mencetak balasannya. Terakhir, kode mencetak plugins: a, b (2) dan themes: ..., atau none (0) jika list kosong.

Kodemu ditulis di registry.rb, plugin.rb, dan theme.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

require_relative 'registry'
require_relative 'plugin'
require_relative 'theme'

# Kode input/output yang disediakan: biarkan apa adanya
input = []
while (line = gets)
  input << line.chomp
end
input.each do |line|
  kind, name = line.split
  target = kind == "plugin" ? Plugin : Theme
  puts target.register(name)
end
[["plugins", Plugin], ["themes", Theme]].each do |label, klass|
  list = klass.entries.empty? ? "none" : klass.entries.join(", ")
  puts "#{label}: #{list} (#{klass.count})"
end
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Ruby online