方法应该修改Ruby中的实例变量吗?
我正在用Ruby编写一个编译器,我有许多类,其中实例方法将修改实例变量。例如,my lexer(在代码中查找标记的部分)的工作原理如下:方法应该修改Ruby中的实例变量吗?,ruby,Ruby,我正在用Ruby编写一个编译器,我有许多类,其中实例方法将修改实例变量。例如,my lexer(在代码中查找标记的部分)的工作原理如下: class Lexer attr_accessor :tokens def initialize(input) @input = input @tokens = nil end def lex! # lex through the input... # @tokens << { lexeme:
class Lexer
attr_accessor :tokens
def initialize(input)
@input = input
@tokens = nil
end
def lex!
# lex through the input...
# @tokens << { lexeme: 'if', kind: :if_statement }
@tokens
end
end
lexer = Lexer.new('if this then that')
lexer.lex! # => [ { lexeme: 'if', kind: :if_statement }, ... ]
lexer.tokens # => [ { lexeme: 'if', kind: :if_statement }, ... ]
根据您的设计目标和lexer的使用方式,两者都是有效的 您真的需要一个包含令牌的实例变量吗?例如,lexer是否需要将其用于其他用途
如果不是,我倾向于不使用实例变量,而您也不需要太多的理由(“例如,这个实例变量会被其他系统交互改变吗)。在您的实例的方法中变异一个实例变量是绝对有效的(这就是为什么它们首先存在的原因)。然而,某个数据段是否应该保存在实例变量中取决于实例的使用方式 您可以将实例变量视为实例的状态,将实例视为实例变量的状态管理器。如果您有一个
计数器
类,例如,使用递增
和递减
方法,那么计数器的当前值显然是状态的一部分,并且这些方法会对其进行变异
一个很好的经验法则是:你要来回传递数据吗?如果是,那么它可能应该是一个实例变量。如果您不是,那么它实际上不是实例状态的一部分,应该保持在实例状态之外。就你而言:
lexer = Lexer.new
tokens = lexer.lex('my statement')
lexer.do_something_else tokens # if you do that, then lexer should be aware of the tokens and keep it in an instance variable, if not: why bother ?
作为结论,这完全取决于
Lexer
是一个功能实用类还是它的实例需要有状态。不,它不使用@tokens
做任何其他事情。我想这基本上回答了我的问题,谢谢@这是一种功能性和非功能性的方法,真的。
lexer = Lexer.new
tokens = lexer.lex('my statement')
lexer.do_something_else tokens # if you do that, then lexer should be aware of the tokens and keep it in an instance variable, if not: why bother ?