[λ²μ] Ruby Modules(λ£¨λΉ λͺ¨λ)
π‘μλ³ΈκΈ : https://alchemists.io/articles/ruby_modules
λ£¨λΉ λͺ¨λμ λμ μμ€μμ λ€μκ³Ό κ°μ μ£Όμ μ΄μ μ μ 곡ν©λλ€.
- Namespaces(λ€μμ€νμ΄μ€): λ€μμ€νμ΄μ€λ₯Ό μ§μ νκ³ , κ°μ²΄λ₯Ό ꡬμ±νκ³ , κ°μ²΄λ₯Ό μ€μ²©ν μ μμ΅λλ€.
- Multiple Inheritance(λ€μ€ μμ): λ€μ€ μμμ μ 곡νμ¬ ν΄λμ€ λ° μΈμ€ν΄μ€ μμ€μμ κΈ°μ‘΄ κ°μ²΄μ μΆκ° λ©μλ ννλ‘ νμλ₯Ό μΆκ°ν μ μμ΅λλ€.
- Functions(ν¨μ): λ€λ₯Έ λ£¨λΉ κ°μ²΄μ²λΌ μ§μ λ©μμ§λ₯Ό μ λ¬ν μ μλ μμ ν¨μν λ©μλλ₯Ό μΊ‘μν ν©λλ€.
μ΄ κΈμμλ μ΄ κΈ°λ₯μ μ΄ν΄λ³΄λλ° μκ°μ ν μ ν μμ μ΄λ, μ§κΈ λ°λ‘ μμν΄λ³΄κ² μ΅λλ€.
Object Hierarchy(κ°μ²΄ κ³μΈ΅ ꡬ쑰)
μλ μλ μ½μμμ λ³Όμ μλ λ΄μ©μ κ·Έλ¦° κ·Έλ¦Όμ λλ€.
Module.ancestors.reverse
# [
# BasicObject,
# Kernel,
# Object < BasicObject,
# Module < Object
# ]
Class.ancestors.reverse
# [
# BasicObject,
# Kernel,
# Module < Object,
# Class < Module
# ]
λͺ¨λκ³Ό ν΄λμ€λ₯Ό λ€μκ³Ό κ°μ΄ μκ°ν μ μμ΅λλ€.
- Functional(module) - ν¨μν(λͺ¨λ)
- Object Oriented(classes) - κ°μ²΄ μ§ν₯(ν΄λμ€)
λ¬Όλ‘ λ£¨λΉμ κ±°μ λͺ¨λ κ²μ΄ λͺ¨λμ ν¬ν¨ν κ°μ²΄μ΄μ§λ§, μ΄λ μ μ©ν νλ μμν¬κ° λ μ μμ΅λλ€.
Namespaces(λ€μμ€νμ΄μ€)
λͺ¨λμ μν€ν μ² λ΄μμ κ°μ²΄μ λ€μμ€νμ΄μ€λ₯Ό μ§μ νκ³ κ΅¬μ±νλ κΈ°λ³Έ λ°©λ²μ λλ€.
module Models
Location = Data.define :latitude, :longitude
end
λ¬Όλ‘ ν΄λμ€λ₯Ό μλ‘ μ€μ²©ν μλ μμ§λ§ μ€μ²©λ ν΄λμ€ μν°ν¨ν΄μ΄λ―λ‘ λλ¬Έ κ²½μ°μ²λΌ λΉκ³΅κ° λ΄λΆ ν΄λμ€κ° νμν κ²½μ°κ° μλλΌλ©΄ κΆμ₯νμ§ μμ΅λλ€. μΆκ° ꡬμ±μ μν΄ λ€μμ€νμ΄μ€λ₯Ό μ€μ²©ν μλ μμ΅λλ€.
module One
module Two
module Models
Location = Data.define :latitude, :longitude
end
end
end
μμ λ°©λ²μ λͺ¨λμ λ€μ¬μ°κΈ°νμ¬ μ€μ²©νλ κΆμ₯ λ°©λ²μ λλ€. λλ Flat ꡬ쑰λ₯Ό μ¬μ©ν μλ μμ§λ§ μ΄λ Flat λͺ¨λ μν°ν¨ν΄μΌλ‘ κ°λ ₯ν κΆμ₯νμ§ μμ΅λλ€.
module One::Two::Models
Location = Data.define :latitude, :longitude
end
λ€μμ€νμ΄μ€λ‘μμ λͺ¨λμ μ μ°μ± λλΆμ μ€μ²©μ μ½μμ μΆλ ₯νμ¬ κ³μΈ΅ ꡬ쑰λ₯Ό λΉ λ₯΄κ² κ²μ¬ λ° λλ²κΉ ν μ μμ΅λλ€.
module One
module Two
module Models
puts Module.nesting
Location = Data.define :latitude, :longitude
end
end
end
# One::Two::Models
# One::Two
# One
μμ κ°μ΄ λͺ¨λμ μ¬μ©νμ¬ μ½λλ₯Ό ꡬμ±νκ³ κ΅¬μ‘°μ μλ―Έλ₯Ό λΆμ¬νλ λ°©λ²(putsλ¬Έ μ μΈ)μ΄ μ¬λ°λ₯Έ λ°©λ²μ λλ€.
Hooks
Hookμ μ¬μ©νλ©΄ κ°μ²΄ λ΄μμ λͺ¨λμ΄ μ μλ λ μΆκ° λμμ μνν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ λ©ννλ‘κ·Έλλ°κ³Ό κ°μ κ³ κΈ κΈ°λ₯μ ꡬνν μ μμ΅λλ€. 4κ°μ§ κΈ°μ‘΄ Hookμ΄ μμ΅λλ€.
- .extended : ν΄λμ€ λ©μλλ₯Ό νμ₯ν©λλ€. descendant(μμ)λΌλ λ¨μΌ μΈμλ₯Ό λ°μ΅λλ€.
- .included : μΈμ€ν΄μ€ λ©μλλ₯Ό ν¬ν¨ν©λλ€. descendant(μμ)λΌλ λ¨μΌ μΈμλ₯Ό λ°μ΅λλ€.
- .prepended : κ°μ²΄λ₯Ό μλΈν΄λμ€ λμ μνΌν΄λμ€λ‘ λ§λ€μ΄ μμ μ€λ κ°μ²΄ μμ λ©μλλ₯Ό μΆκ°ν©λλ€. ancestor(μ‘°μ)λΌλ λ¨μΌ μΈμλ₯Ό λ°μ΅λλ€.
- .using : κΈ°μ‘΄ λ©μλλ₯Ό ꡬ체ννκ±°λ μ λ©μλλ₯Ό μ½μ ν©λλ€. target μ΄λΌλ λ¨μΌ μΈμλ₯Ό λ°μ΅λλ€. targetμ μΈλΆνν λμμ λλ€. μΈλΆνλ λ¬Έμμ λ²μλ₯Ό λ²μ΄λμ§λ§ λ μμΈν μμλ³΄λ €λ©΄ μΈλΆν λ¬Έμλ₯Ό μ°Έκ³ νμΈμ.
μκ°μ μΌλ‘λ μμ κ°μ΅λλ€.
module Demo
def self.extended(descendant) = super
def self.included(descendant) = super
def self.prepended(ancestor) = super
end
Class.new.extend(Demo).singleton_class.ancestors
# [
# #<Class:#<Class:0x0000000130c101e8>>,
# Demo,
# #<Class:Object>,
# #<Class:BasicObject>,
# Class,
# Module,
# Object,
# Kernel,
# BasicObject
# ]
Class.new.include(Demo).ancestors
# [
# #<Class:0x0000000130c58038>,
# Demo,
# Object,
# Kernel,
# BasicObject
# ]
Class.new.prepend(Demo).ancestors
# [
# Demo,
# #<Class:0x00000001222123c0>,
# Object,
# Kernel,
# BasicObject
# ]
μ΄λ₯Ό μ’ λ μΈλΆννκΈ° μν΄ λͺ κ°μ§ μ°Έκ³ μ¬νμ μ€λͺ ν©λλ€.
- μ΅λͺ ν΄λμ€(Class.newλ₯Ό ν΅ν)λ #<Class:0x00*> λ‘ νμλλ λ°λͺ¨μ©μ λλ€.
- descendant(μμ) κ³Ό ancestor(μ‘°μ) μ μ¬μ©νλ©΄ κ°λ μ±μ΄ ν₯μλλ―λ‘ extending(νμ₯), including(ν¬ν¨), prependingνλ κ°μ²΄μ μ’ λ₯λ₯Ό λΉ λ₯΄κ² μ΄ν΄ν μ μμ΅λλ€.
- extending(νμ₯), including(ν¬ν¨) μ Demoλ νμ μμ ν΄λμ€μ λλ€. μμ λΆμΌ λλ§ Demoκ° νμν΄λμ€κ° λ©λλ€. μ΄ κ³μΈ΅ ꡬ쑰λ₯Ό μκΈ°μν€κΈ° μν΄ including, extending ν λλ descendant(μμ) λ₯Ό μ¬μ©νκ³ μμ λΆμΌ λλ ancestor(μ‘°μ) λ₯Ό μ¬μ©νλ μ΄μ λ μ¬κΈ° μμ΅λλ€. μ΄ μ©μ΄λ₯Ό μ¬μ©νμ¬ μμ μ μ½λλ₯Ό κ°λ μ± μκ² μ μ§νμΈμ.
μ΄μ κ΄λ ¨νμ¬ νμ ν΄λμ€κ° λΆλͺ¨ ν΄λμ€μμ μμν λ νμ ν΄λμ€κ° μμμΌλ‘ μ λ¬λκΈ° λλ¬Έμ Class.inherited νΉμ μΈμλ‘ descendant λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
class Parent
def self.inherited(descendant) = super
end
λͺ¨λμ ν¬ν¨νκ³ μ΄μ λμΌν ꡬνμ μ¬μ©νλ κ²½μ° λ€μμ ν΅ν΄ ν΄λμ€μ κΈ°λ₯μ΄ ν¬ν¨λμ΄ μλμ§ νμΈνλ μ¬λ¬ κ°μ§ λ°©λ²μ΄ μμ΅λλ€.
Example.include? Demo # => true
Example < Demo # => true
Example.ancestors.include? Demo # => true
κΈ°λ₯ μΆκ°
λ€μλ¨κ³λ‘ λ΄λ €κ°λ©΄, Module#include μ μν΄ νΈμΆλλ Module#append_features κ° μμ΅λλ€. μ΄ λ©μλλ₯Ό ꡬννλ©΄, μ°©νκ² μ¬μ©ν μλ μκ³ , μ νκ² μ¬μ©ν μλ μμ΅λλ€. μ¬κΈ° #append_featrues κ° μ μ©λλ μν©μ 보μ¬λλ¦¬κ² μ΅λλ€.
module Demo
def self.append_features descendant
descendant.module_eval do
def label = "π"
end
end
end
Example = Class.new { include Demo }
Example < Demo # nil
Example.new.label # "π"
μμμ μ°λ¦¬λ #include μ μν΄ νΈμΆλλ #append_features λ₯Ό μ¬μ©νμ¬ νμ κ°μ²΄μ #label λ©μλλ₯Ό λμ μΌλ‘ μμ±νμ¬ λμμ λ³κ²½νκ³ μμ΅λλ€. μ΄κ²μ #include λ₯Ό μ§μ νΈμΆν λ λ°μνλ κΈ°λ³Έ κΈ°λ₯μ μ μ©νμ§ μκ² λ§λ€μ΄, μ¦ superλ₯Ό νΈμΆνμ§ μμμΌλ‘μ¨ #include μ λμμ λ³κ²½νλ κ²μ λλ€. μ΄λ° λ°©μμ μ¬μ©νμ§ λ§μΈμ! #label λ©μλλ₯Ό λκ° μ μνλμ§ μ¨κΈ°λ©΄ λλ²κΉ μ ν° κ³ ν΅μ μ΄λν μ μμ΅λλ€.
μ’μ μΈ‘λ©΄μμλ, #append_features λ₯Ό νμ©νμ¬ μΆκ°μ μΈ κ΅¬ν, λλ²κΉ , μ μ΄ κ²μ¬ λ±μ μΆκ°ν μ μμ΅λλ€. μ¬κΈ°μλ λλ²κΉ λͺ©μ μΌλ‘ μ΄λ€ κ²μ΄ ν¬ν¨λμλμ§ λ‘κ·Έλ₯Ό λ¨κΈ°λ λ°©μμΌλ‘ #append_features λ₯Ό μ’μ μ¬λ‘λ‘ μ¬μ©ν μμμ λλ€.
module Demo
def self.append_features descendant
puts "Including #{name.inspect} in #{descendant.name.inspect}."
super
end
end
class Example
include Demo
end
# Including "Demo" in "Example".
ν° νμλ ν° μ± μμ΄ λ°λ¦ λλ€. - Uncle Ben, Spiderman
μ μ΄ μλ μ μ΄ λμΈμ.
Multiple Inheritance(λ€μ€ μμ)
λ€μ€ μμ, νν mixin(λ―Ήμ€μΈ)μ΄λΌκ³ λΆλ¦¬λ λ°©μμ μ¬λ¬ κ°μ²΄μ κ³΅ν΅ κΈ°λ₯μ ν¬ν¨(include), νμ₯(exclude) λλ μ μ²λ¦¬(prepend)ν μ μκ² ν΄μ€λλ€. (μμ Hook μΉμ μμ λ€λ£¬κ² μ²λΌ). νΉν, λ©μλλ₯Ό κ³΅ν΅ λͺ¨λλ‘ μΆμΆνλ©΄ μ΄ κ³΅ν΅ λͺ¨λμ μ¬μ©νλ λͺ¨λ κ°μ²΄κ° λμΌν λ°μ΄ν° λ° μμ λ©μλμ μμ‘΄ν μ μλ€λ μ묡μ μΈ κ°μ μ νκ² λ©λλ€.
module Nameable
def full_name = [first_name, last_name].compact.join " "
end
User = Data.define :first_name, :last_name do
include Nameable
end
User[first_name: "Jayne", last_name: "Doe"].full_name
# Jayne Doe
Nameable λͺ¨λμ΄ #first_name κ³Ό #last_name λ©μλκ° μλ€κ³ κ°μ νλ μ μ μ£Όλͺ©νμΈμ. μ΄ μ묡μ μΈ κ³μ½μ Nameable μ μ΄λ¬ν λ©μλλ₯Ό κ°μ§ κ°μ²΄μμ μ¬μ©νκ² λ κ²μ΄λΌκ³ κ°μ ν©λλ€. μ΄λ° λ°©μμ΄ κ·Ήλ¨μΌλ‘ μΉμ°μΉλ©΄, λ¨μΌ λͺ¨λμμ μ¬λ¬ λ©μλλ₯Ό μ¬μ©ν λ, νΉν μλ‘μ΄ λμμ΄ μΆκ°λλ©΄μ κ°μ²΄λ€μ΄ μλ‘ λ€λ₯΄κ² λ³ννκΈ° μμνλ©΄, μ΄λ₯Ό 리ν©ν°λ§ νκ±°λ μ 리νλ κ²μ΄ λ§€μ° μ΄λ €μμ§ μ μμ΅λλ€.
μ΄κ²μ΄ λ°λ‘ μ¬λ¬ μμμ 무λΆλ³νκ² μ¬μ©νμ¬ λ³΅μ‘ν ꡬνμ λ§λ€μ΄λ΄λ λ§μ νλ€μ΄ κ³€κ²½μ λΉ μ§λ μ΄μ μ λλ€. μλ₯Ό λ€μ΄, λ€μ― κ° μ΄μμ λͺ¨λλ‘ λμμ λλκ³ , λ€μκ³Ό κ°μ κ°μ²΄κ° λ§λ€μ΄μ§ μν©μ μκ°ν΄λ΄ μλ€.
class Demo
include Comparable
include Geolocatable
include Indexable
include Nameable
include Observable
include Searchable
end
μμ μν©μ λΆλͺ κ·Ήλ¨μ μ΄μ§λ§, μ¬λ¬ λ² μ΄λ° κ²½μ°λ₯Ό λͺ©κ²©ν μ μ΄ μμ΅λλ€. μμ κ°μ ꡬνμλ λͺκ°μ§ λ¬Έμ μ μ΄ μμ΅λλ€.
- νΌλμ€λ¬μ΄ λμ: Demo ν΄λμ€λ λ무 λ§μ λμμ κ°μ§κ³ μμ΅λλ€. λΉκ΅ν μλ μκ³ , μ§λ¦¬μ μμΉλ₯Ό μΆμ ν μλ μκ³ , μΈλ±μ±μ΄ κ°λ₯ν λ± λ€μν κΈ°λ₯μ΄ μΆκ°λμ΄ μμ΅λλ€. μ¦, λκ΅°κ° νΈλ¦¬ν¨κ³Ό κ²μΌλ¦μΌλ‘ μΈν΄ κ°μ²΄μ λ³Έλ λͺ©μ μ κΉμ΄ μκ°νμ§ μκ³ μ¬λ¬ κΈ°λ₯μ λμ§λμ§ λΆμΈ κ²μ λλ€. κ°μ²΄μ λ¨μΌ λͺ©μ μΈ μ΄ν΄ν νμλ, κΈ°λ₯μ κ°λ³ κ°μ²΄λ‘ λλμ΄ SOLID μμΉμ S μΈ λ¨μΌ μ± μ μμΉ(Single Responsibility Principle)μ λ°λ₯΄λ κ²μ΄ λ μ μ ν©λλ€.
- μμμ μ€μμ±: μ¬κΈ°μ κ° λͺ¨λμ μνλ²³ μμλ‘ ν¬ν¨μμΌ°μ§λ§, κ·Έ μμκ° νμ μ³μ§λ μμ μ μμ΅λλ€. νΉν μΌλΆ λͺ¨λμ΄ μ΄μ λͺ¨λκ³Ό λμΌν λ©μλλ₯Ό ν¬ν¨νκ³ μλ€λ©΄ λ¬Έμ κ° λ μ μμ΅λλ€. λ€μ λ§ν΄, λμ€μ ν¬ν¨λ λͺ¨λμ΄ μ΄μ λͺ¨λλ³΄λ€ μ°μ νκ² λλ©°, μ΄λ‘ μΈν΄ μΆ©λνλ λμμ΄ λ°μν μ μμ΅λλ€. μ£Όμνμ§ μμΌλ©΄ μ΄λ¬ν μΆ©λμ λΆνμνκ² λ³΅μ‘ν λλ²κΉ μν©μ μ΄λν μ μμ΅λλ€.
κ°μ₯ μ¬κ°ν λ¬Έμ λ Active Support Concernsμ λλ€. μ΄κ²μ κΈ°λ³Έμ μΌλ‘ λ€μ€ μμμ μ₯λ €ν©λλ€. λ λμ μ μ Concernsκ° νΉμ ν Rails λ°©μΈμ΄κΈ° λλ¬Έμ λ μ΄μ μμν Ruby κΈ°λ₯μ μ¬μ©ν μ μλ€λ κ²μ λλ€. μ¦, κΈ°λ₯μ λΌμ΄λΈλ¬λ¦¬λ gemμΌλ‘ μΆμΆνμ¬ μ¬λ¬ νλ‘μ νΈμμ μ¬μ¬μ©νλ € ν λ λ λ§μ λ Έλ ₯μ΄ νμν©λλ€. μμν Rubyλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. κ·Έλ κ² νλ©΄ νμν λ λ μμ λ‘κ² λ¦¬ν©ν°λ§ν μ μλ μ μ°μ±μ κ°μ§ μ μκΈ° λλ¬Έμ λλ€.
λ€μ€ μμμ μ μ€νκ² μ¬μ©νλ©΄ κ°λ ₯ν μ μμ§λ§, κΈ°μ‘΄ κ°μ²΄μ μ½λλ₯Ό μ€μ΄κΈ° μν΄ μ¬λ¬ λ©μλλ₯Ό κ³΅ν΅ λͺ¨λλ‘ μΆμΆνλ κ²μ κ²°μ½ νλͺ ν μ νμ΄ μλλλ€. λμ , Command Patternμ ν΅ν΄ κΈ°λ₯μ μΆμΆν ν, νμν μμ μ μμ‘΄μ± μ£Όμ μ ν΅ν΄ νμν κ²μ μ£Όμ νλ λ°©λ²μ κ³ λ €νμΈμ. μμλ³΄λ¨ μ‘°ν©(Composition)μ μ¬μ©νλ κ²μ΄ μ₯κΈ°μ μΌλ‘ μ μ§κ°λ₯ν μ½λμ ν¨μ¬ μ 리ν©λλ€. λν, λ κ³ κΈμ€λ¬μ΄ Module Builder Patternλ λ λ€λ₯Έ ν΄κ²°μ± μ΄ λ μ μμ΅λλ€.
Functions(ν¨μ)
λλ€λ₯Έ μ₯μ μ κΈ°λ₯μ λ©μλμ λ Όλ¦¬μ κ·Έλ£Ήμ λ§λλ κ²μ λλ€. μλ₯Όλ€μ΄, μνλ μΆκ°μ μΈ λμμ΄ νμνμ§ μμ ν¨μλ€μ λͺ¨μμ μν΄ MyModule.my_function κ³Ό κ°μ λ°©μμΌλ‘ μμ ν κΈ°λ₯μ μΈ μ΄μ λ‘ λͺ¨λ λ΄μ ν¨μλ₯Ό κ·Έλ£Ήννλ κ²μ λ Όλ¦¬μ μΌλ‘ νλΉν©λλ€.
μ΄λ¬ν μμ μ extend self μ #module_function μ μ¬μ©νμ¬ μνν μ μμΌλ©°, μ¬μ ν λͺ¨λμ ν¬ν¨(include), νμ₯(extend), λλ μ μ²λ¦¬(prepend)ν μ μλ μ΅μ λ μ 곡ν©λλ€. κ°κ°μ λ°©λ²μ μλμ μμ±λμ΄ μμ΅λλ€.
Extending Self
Extending Selfλ₯Ό μ¬μ©νλ©΄ μΌλ°μ μΌλ‘ μΈμ€ν΄μ€ λ©μλλ‘ λμνλ λ©μλλ₯Ό ν΄λμ€ λ©μλλ‘ λ³κ²½ν μ μμ΅λλ€.
module Demo
extend self
def label = "Demo"
end
Demo.label # "Demo"
Demo.singleton_methods.include? :label # true
κ°μμ±μ ν΄λμ€μ ν¬ν¨λ λλ λ³νμ§ μμμ΅λλ€.
MyClass = Class.new { include Demo }
my_class = MyClass.new
my_class.label # "Demo"
my_class.public_methods.include? :label # true
MyClass.singleton_methods.include? :label # false
μ μμμμ λ³Ό μ μλ―μ΄, Demo λͺ¨λμ΄ MyClassμ ν¬ν¨λλ©΄ #label λ©μλλ μΈμ€ν΄μ€ λ©μλκ° λκ³ , μ¬μ ν κ³΅κ° μνλ‘ μ μ§λ©λλ€.
λν μ΄λ¬ν λ©μλλ€μ λͺ¨λ μ€λ²λΌμ΄λν μ μμ΅λλ€.
module Demo
extend self
def label = "Demo"
end
Demo.label # "Demo"
module Demo
def label = "Override"
end
Demo.label # "Override"
μ μ½λμμ Demo λͺ¨λμ label λ©μλκ° μ²μμ “Demo” κ°μ λ°ννμ§λ§, λμΌν λͺ¨λ λ΄μμ λ€μ μ μλλ©΄μ “Override”λ‘ μ€λ²λΌμ΄λλμμ΅λλ€. μ΄λ Rubyμμ λͺ¨λμ΄λ ν΄λμ€ λ΄ λ©μλλ₯Ό λ€μ μ μνλ κ²μ΄ κ°λ₯ν¨μ 보μ¬μ€λλ€.
Module Functions
λͺ¨λμ λͺ¨λ λ©μλλ₯Ό ν¨μλ‘ μ§μ νλ©΄ “self”λ‘ νμ₯ν λ μ μ¬ν λμμ κ°μ§ μ μμ§λ§, λ λμ μΊ‘μνλ₯Ό μν΄ κ°μμ±μ λ³κ²½νλ μΆκ°μ μΈ μ΄μ μ μ»μ μ μμ΅λλ€.
module Demo
module_function
def label = "Demo"
end
Demo.label # "Demo"
Demo.singleton_methods.include? :label # true
ν΄λμ€μ ν¬ν¨λ λ κ°μμ±μ΄ λ³κ²½λμ§λ§, μ΄μ μ selfλ₯Ό νμ₯ν λμ λμΌν λμμ 보μ΄λ κ²μ νμΈν μ μμ΅λλ€.
MyClass = Class.new { include Demo }
my_class = MyClass.new
my_class.label # `NoMethodError`
my_class.private_methods.include? :label # true
my_class.public_methods.include? :label # false
MyClass.singleton_methods.include? :label # false
#label λ©μλκ° μ΄μ privateλ©μλκ° λμμ΅λλ€. μ΄λ selfλ₯Ό νμ₯νλ κ²λ³΄λ€ μ μ ν μΊ‘μνλ₯Ό 보μ₯νλ μΆκ°μ μΈ μ΄μ μ΄ μμ΅λλ€.
λͺ¨λ ν¨μμ λ λ€λ₯Έ μΈ‘λ©΄μ, ν λ² ν¬ν¨λλ©΄ μλ λμμ΄ λ³΅μ¬λ³Έμ΄ λλ€λ κ²μ λλ€.
module Demo
module_function
def label = "Demo"
end
Demo.label # "Demo"
module Demo
def label = "Override"
end
Demo.label # "Demo"
module Demo
module_function
def label = "Override"
end
Demo.label # "Override"
μλ κΈ°λ₯μ μ¬μ μνλ €κ³ μλν λ μλ λμλ§ λνλ΄λ κ²μ νμΈν μ μμ΅λλ€. μ΄λ λͺ¨λ ν¨μλ₯Ό ν¬ν¨νλ©΄ κ·Έκ²λ€μ΄ μλ³Έμ 볡μ¬λ³Έμ΄ λκΈ° λλ¬Έμ λλ€. λ©μλλ₯Ό μ¬μ μνκ³ λ§μ§λ§ μμμμ module_functionμ μ¬μ©ν λλ§ μ€λ²λΌμ΄λκ° μλνλ κ²μ λ³Όμ μμ΅λλ€. μ΄λ extend self λ₯Ό μ¬μ©ν΄ μ€λ²λΌμ΄λν κ²½μ° μκΈ°μΉ μκ² λμμ΄ λ³κ²½λλ λΆμμ©μ μΌμΌν¬ μ μλ€λ μ μμ μ΄μ μ΄ μμ΅λλ€.
λͺ¨λμ ν¬ν¨νκ±°λ νμ₯ λ° μ μ²λ¦¬ν λλ extend self λμ module_function μ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. κ·Έ μ΄μ λ κ°μ²΄ APIμ λ²μλ₯Ό μκ²(private) μ μ§νλ κ²μ΄ ν¬κ²(public)μ μ§νλ κ²λ³΄λ€ 리ν©ν λ§μ λ μ½κ² ν μ μκ³ , λ€λ₯Έ κ°μ²΄κ° μκ±°λ μ κ·Όν΄μλ μλλ λ°μ΄ν°μ λν μ κ·Όμ μ΅μνν μ μκΈ° λλ¬Έμ λλ€. λ©μλλ₯Ό publicμΌλ‘ μ¬μ©ν νμκ° μμλλ§ ν΄λΉ λ©μλλ₯Ό publicμΌλ‘ λ§λλκ²μ΄ λ°λμ§ ν©λλ€.
module_function μ¬μ©μ protected λ private μ μ μ¬νκ² μλν©λλ€. νλ² μ μνλ©΄ κ·Έ μλμ λͺ¨λ λ©μλκ° λͺ¨λ ν¨μκ° λκ±°λ, κΈ°νΈλ₯Ό μ 곡νμ¬ νΉμ λ©μλλ₯Ό λͺ¨λ ν¨μλ‘ μ§μ ν μλ μμ΅λλ€. μμλ‘λ module_duction :label μ λλ€.
Module Builder Pattern
κΈ°λ³Έμ μΌλ‘ λͺ¨λμ μνλ₯Ό μ μ₯νκΈ° μκΈ° λλ¬Έμ Namespace μ 리, λ€μ€ μμ, λλ μμ ν¨μ λμμ μ§ν©μ λ§λ€κΈ°μ μ ν©ν©λλ€. κ·Έλ κΈ° λλ¬Έμ λͺ¨λμ Namespaceμ λ§€μ° μ μ©ν©λλ€. κ·ΈλΌμλ λΆκ΅¬νκ³ , Module Builder Patternμ ν΄λμ€μ λͺ¨λμ λμμ μ¬μ©ν μ μλ λ°©λ²μ μ 곡νμ¬ μ΅λν κΈ°λ₯μ±κ³Ό μ¬μ¬μ©μ±μ μ»μ μ μκ² ν©λλ€. Module Builder Patternμ λν μ¬μΈ΅μ μΈ μ€λͺ μ μ΄ κΈμ λ²μλ₯Ό λ²μ΄λλ―λ‘ λ μμΈν μκ³ μΆλ€λ©΄ λ§ν¬λ₯Ό ν΅ν΄ νμ΅νμΈμ.
λ€μ΄λ°
λ€μ΄λ°μ μ΄λ ΅μ§λ§ λ§€μ° μ€μν μμ μ λλ€. μμμ λ Όμν λ°μ κ°μ΄, λͺ¨λμ μ΄λ¦μ μ§μ ν λ κ³ λ €ν΄μΌ ν λκ°μ§λ λ€μκ³Ό κ°μ΅λλ€.
- λͺ μ¬: μ‘°μ§νλ₯Ό μν Namespace
- νμ©μ¬: μμ€ν μ μ¬λ¬ λΆλΆ κ°μ κ³μ½ μν μ νμ¬ μ΄λ€ μμ μ΄ μνλ μ μμΌλ©°, μ΄λ»κ² νΈμΆλμ΄μΌ νλμ§ μ§μ νλ μΈν°νμ΄μ€. μ΄ μΈν°νμ΄μ€λ Hookμ ν΅ν΄ λ€μ€ μμμ μ¬μ©νμ¬ μΈν°νμ΄μ€μ λ§λ λμμ μ 곡ν©λλ€.
λͺ μ¬μ κ²½μ° Parsers, Processors, Handlers, Clients μ²λΌ 볡μν λͺ μ¬λ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. κ·Έ μ΄μ λ λμΌν λ€μμ€νμ΄μ€ λ΄μμ μ μ¬ν λμμ νλ μ¬λ¬ κ°μ²΄λ₯Ό μ‘°μ§ννκΈ° λλ¬Έμ 볡μνμ΄ λ Όλ¦¬μ μΌλ‘ λ§κΈ° λλ¬Έμ λλ€.
νμ©μ¬μ κ²½μ°, λͺ¨λ μ΄λ¦μ -able μ λ―Έμ¬λ₯Ό λΆμ΄λ κ²μ΄ μ’μ΅λλ€. μ΄λ Ruby μ½μ΄ λΌμ΄λΈλ¬λ¦¬μμλ μΆ©λΆν μμκ° μμ΅λλ€.
μ΄λ€ μ¬λμ΄ -able λμ -ing μ μ μνλ κ²μ λ³Έ μ μ΄ μλλ°, κ·Έ μ£Όμ μ£Όμ₯μ -ing κ° -able λ³΄λ€ μμ°μ€λ½κ² λ€λ¦°λ€λ κ²μ΄μμ΅λλ€.
- Accessable → Accessing
- Containable → Containing
- Infusible → Infusing
- Searchable → Searching
ν₯λ―Έλ‘μ΄ μκ°μ΄μ§λ§, νμ©μ¬ λμ λμ¬λ₯Ό μ¬μ©νλ κ²μ μ§μνλ κ²μ΄ μ’μ΅λλ€. κ·Έ μ΄μ λ νλμ κ°λ₯νκ² νλ€λ μλ―Έμμ -able μ΄ κ°μ‘°λκΈ° λλ¬Έμ λλ€.
μ¦, νλμ μννλ κ²μ΄ μλλΌ κ°λ₯νκ² νλ κ²μ λλ€. Rubyκ° μΈν°νμ΄μ€λ₯Ό λ€μ΄λ°νλ λ°©μμμ λ²μ΄λλ©΄ λͺ¨λμ μνΈμμ©ν λ λ νΌλμ€λ½κ² λ§λ€μ μμ΅λλ€. κΆκ·Ήμ μΌλ‘ μΌκ΄μ±μ΄ μ€μν©λλ€. μΆκ°μ μΌλ‘ μ€λͺ νμλ©΄, μ μμ μ΄λ¬ν κ·μΉμ μ κ° μμ±ν gemμμλ λ°λ₯΄κ³ μμ΅λλ€.
κ²°λ‘
μ΄ κΈμ΄ λͺ¨λμ΄ μ 곡ν μ μλ λͺ¨λ κΈ°λ₯μ λ€λ£¬ κ²μ μλμ§λ§, μ¬λ¬λΆμκ² λμμ΄ λμκΈ°λ₯Ό λ°λλλ€. μμ μ μ½λλ₯Ό μ€κ³ν λ, λ€μ΄λ°, ꡬ쑰ν, κ°μ²΄μ λ©μλμ ꡬλΆ, μμ, μ‘°ν© λ±μ μμλ₯Ό μ μ€νκ² κ³ λ €νμ¬ μ½λλ₯Ό μ½κ² λ°κ²¬νκ³ , μ΄ν΄νλ©°, μ¬μ©ν μ μλλ‘ νμΈμ. μ’μ μ€κ³λ μ½λμ κ°λ μ±, μ μ§ λ³΄μμ±, κ·Έλ¦¬κ³ μ¬μ¬μ©μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€.