我是ruby(和OOP最佳实践)的新手,我目前正在进行一些涉及课程的练习。其中一个让我制作一个字典,将“关键字”映射到它们的“定义”。以下是简化版本:
class Dictionary
attr_accessor :entries, :keywords
def initialize(opts = {})
@entries = opts
@keywords = opts.keys.sort
end
end
无论如何,我有一个关于在类实现中改变成员变量值的问题。下面我有一个实例方法的例子,我需要更新@entries和@keywords的值。
def add(entry)
if entry.instance_of?(Hash)
@entries = @entries.merge!(entry)
else
@entries = entries.merge!({entry => nil})
end
@keywords = @entries.keys.sort
end
在上面的例子中,我通过调用'='运算符来使用public setter方法 这有一些轻微的性能缺陷,因为我在评估r值时创建了一个新的Hash。
我知道在访问变量实例时通常最好使用setter,但我想知道是否有可能(即使不建议)在不使用setter的情况下更改类的成员变量?例如,在像python这样的语言中,如果不使用getter / setter,可以在成员变量上调用成员函数来改变其值。然而,在ruby中,似乎需要获取getter和setter(除非我弄错了)。我想也许有一种方法可以实现一个getter,因为它返回对成员变量的引用,所以它的行为就像直接访问一样?我想象的方式,结果将看起来像这样一个直观的观点:
def add(entry)
if entry.instance_of?(Hash)
@entries.merge!(entry)
else
@entries.merge!({entry => nil})
end
@keywords.push(entry.keys.first).sort!
end
(在上面的例子中,实际上没有任何成员变量@entries,@ keywords在调用add之后实际更新,但你知道它应该做什么。)如果上面的例子按预期工作,它似乎比第一次实现更有效。
Ruby有没有办法做这样的事情?感谢。
答案 0 :(得分:3)
不,你不是。那里没有setter调用。我通过调用' ='来使用公共setter方法。操作
如果上面的示例确实按预期工作,那么它似乎比第一个实现更有效。
假。这个例子正在做完全相同的事情(除了ivar赋值,这是一条指令),因此,性能将是相同的。始终衡量绩效,不要假设或猜测。
def add(entry)
if entry.instance_of?(Hash)
@entries.merge!(entry)
else
@entries.merge!({entry => nil})
end
@keywords.push(entry.keys.first).sort!
end
在上面的例子中,实际上在调用add之后,没有成员变量@entries,@ keywords实际更新
他们应该更新。必须是调用代码中的错误。顺便说一下,你应该这样写:
def add(entry)
if entry.instance_of?(Hash)
entries.merge!(entry)
else
entries.merge!({entry => nil})
end
keywords.push(entry.keys.first).sort!
end
您已定义了getter方法。很遗憾他们未被闲置。