Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
方法应该修改Ruby中的实例变量吗?_Ruby - Fatal编程技术网

方法应该修改Ruby中的实例变量吗?

方法应该修改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:

我正在用Ruby编写一个编译器,我有许多类,其中实例方法将修改实例变量。例如,my lexer(在代码中查找标记的部分)的工作原理如下:

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 ?