매개변수가 있는 Ruby 클래스에 모듈 포함
9265 단어 rubyprogrammingtutorial
문제:
행동과 약속이 다른 2 개의 수업이 있습니다. 그러나 일부 메서드에는 동일한 코드가 있습니다.
class User
def greeting
puts "Hello!"
end
end
class AdminUser
def greeting
puts "Hello!"
end
end
user = User.new
user.greeting # => "Hello!"
admin = AdminUser.new
admin.greeting # => "Hello!"
Ruby는 단일 상속 언어이며 클래스
User
와 AdminUser
에 이미 다른 기본 클래스가 있는 경우 두 번째 클래스에서 확장할 수 없습니다. 어쨌든, 이러한 클래스에 기본 클래스가 없는 경우 greeting
메서드를 상속하기 위해 두 클래스 모두에 대한 기본 클래스를 만드는 것은 나쁜 방법입니다.최악의 솔루션:
class Base
def greeting
puts "Hello!"
end
end
class User < Base
end
class AdminUser < Base
end
기본 솔루션:
Ruby의 모듈은 단일 상속 제한을 우회하는 방법입니다.
module Greetable
def greeting
puts "Hello!"
end
end
class User
include Greetable
end
class AdminUser
include Greetable
end
작업을 복잡하게 만드십시오.
우리의 앱은 매일 성장하고 있습니다. 수업
User
과 AdminUser
는 행동과 약속이 다릅니다. 각 클래스에는 사람 이름이 있지만 User
에서는 full_name
이고 AdminUser
에서는 nick
입니다.class User
include Greetable
attr_reader :full_name
def initialize(full_name)
@full_name = full_name
end
end
class AdminUser
include Greetable
attr_reader :nick
def initialize(nick)
@nick = nick
end
end
그리고
greeting
메서드에 닉네임이나 전체 이름을 추가하기로 결정합니다. 이 아키텍처에서는 불가능하지만 name
와 같은 세 번째 메서드를 만들고 각 클래스에서 재정의할 수 있습니다.module Greetable
def greeting
puts "Hello, #{name}!"
end
def name
raise NotImplementedError, "not implemented method name"
end
end
class User
include Greetable
attr_reader :full_name
def initialize(full_name)
@full_name = full_name
end
def name
full_name
end
end
class AdminUser
include Greetable
attr_reader :nick
def initialize(nick)
@nick = nick
end
def name
nick
end
end
클래스가 2개 이상인 경우 각 클래스에 숨겨진 메서드를 구현해야 하고 포함할 때마다 메서드
name
를 기억해야 하기 때문에 좋은 변형처럼 보이지 않습니다. 또한 일부 동작을 포함하기 위해 기본 클래스에서 다른 일부를 구현해야 하는 경우 이는 큰 고통이며 개발자의 삶을 쉽게 만들지 않습니다.해결책:
메시지 넣기에 매개변수를 사용하는 메서드
[]
가 있는 새 모듈을 반환하는 하나의 매개변수Greetable
가 있는 모듈name_attribute
에 메서드greeting
를 만듭니다.module Greetable
def self.[](name_attribute)
Module.new do
define_method :greeting do
puts "Hello, #{public_send(name_attribute)}!"
end
end
end
end
class User
include Greetable[:full_name]
attr_reader :full_name
def initialize(full_name)
@full_name = full_name
end
end
class AdminUser
include Greetable[:nick]
attr_reader :nick
def initialize(nick)
@nick = nick
end
end
User.new("Bob").greeting # => "Hello, Bob!"
AdminUser.new("root").greeting # => "Hello, root!"
메모:
define_method
값을 얻기 위해 클로저를 사용해야 하므로 일반적인 def method_name
대신 모듈에서 name_attribute
를 사용하는 것이 중요합니다. def method_name
를 사용하는 경우 클로저는 독립적인 범위를 가지므로 def
코드 내부에서 작동하지 않습니다.즐거운 코딩 되세요 여러분!
Reference
이 문제에 관하여(매개변수가 있는 Ruby 클래스에 모듈 포함), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shved270189/include-modules-in-ruby-classes-with-parameters-2121텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)