gpt4 book ai didi

ruby - 将属性方法委托(delegate)给父对象

转载 作者:数据小太阳 更新时间:2023-10-29 07:11:08 24 4
gpt4 key购买 nike

我有以下类(class):

class Alphabet

attr_reader :letter_freqs, :statistic_letter

def initialize(lang)
@lang = lang
case lang
when :en
@alphabet = ('A'..'Z').to_a
@letter_freqs = { ... }
when :ru
@alphabet = ('А'..'Я').to_a.insert(6, 'Ё')
@letter_freqs = { ... }
...
end
@statistic_letter = @letter_freqs.max_by { |k, v| v }[0]
end

end

foo = Alphabet.new(:en)

这里的核心成员是@alphabet

我想让它成为某种容器类来直接调用 Array 方法

foo[i]
foo.include?

而不是显式访问 @alphabet:

foo.alphabet[i]
foo.alphabet.include?

我知道我可以定义很多方法,比如

def [](i)
@alphabet[i]
end

但我正在寻找“继承”它们的正确方法。

最佳答案

您可以使用 Forwardable (它包含在 Ruby 标准库中):

require 'forwardable'

class Alphabet

extend Forwardable
def_delegators :@alphabet, :[], :include?

def initialize
@alphabet = ('A'..'Z').to_a
end

end

foo = Alphabet.new

p foo[0] #=> "A"
p foo.include? 'ç' #=> false

如果您希望委托(delegate)您的类未定义的所有方法,您可以使用 SimpleDelegator (也在标准库中);它允许您将实例未响应的所有方法委托(delegate)给 __setobj__ 指定的对象:

require 'delegate'

class Alphabet < SimpleDelegator

def initialize
@alphabet = ('A'..'Z').to_a
__setobj__(@alphabet)
end

def index
'This is not @alphabet.index'
end

end

foo = Alphabet.new

p foo[0] #=> "A"
p foo.include? 'ç' #=> false
p foo.index #=> "This is not @alphabet.index"

当委托(delegate)不需要是动态的时,您可以将主类安排为 DelegateClass 的子类,将要委托(delegate)的类的名称作为参数传递并调用 super 在主类的#initialize方法中传递要委托(delegate)的对象:

class Alphabet < DelegateClass(Array)

def initialize
@alphabet = ('A'..'Z').to_a
super(@alphabet)
end

有关 Ruby 中委托(delegate)设计模式的更多信息 here

关于ruby - 将属性方法委托(delegate)给父对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20072649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com