关于Ruby koans about_classes.rb的问题

时间:2016-03-04 00:50:58

标签: ruby methods

这里是来自about_classes.rb的代码。我不确定答案为何[ ][:@name]

class Dog2
def set_name(a_name)
  @name = a_name
end

def test_instance_variables_can_be_set_by_assigning_to_them
    fido = Dog2.new
    assert_equal [ ], fido.instance_variables 
#In this case, fido doesn't have any instance_variables, 
because it is assigned to a new "Dog2" Hash/class which has none methods?

    fido.set_name("Fido")
    assert_equal [:@name], fido.instance_variables 
#In this case, fido has an instance_variable, 
because it uses the set_name methods inherited from "Dog2" classes?
end

assert_raise(SyntaxError) do
  eval "fido.@name"
  # NOTE: Using eval because the above line is a syntax error.
end
#So Eval here means that if the above returns "fido.@name", give it a SyntaxError?

我在这2个案例中添加了一些评论,看看我是否理解正确。

1 个答案:

答案 0 :(得分:2)

当第一个assert_equal被调用时,Dog2实例(fido)没有实例变量,因为没有在初始化程序中或以任何其他方式定义。

set_name被调用时,@name实例变量被设置,所以当第二个assert_equal被调用时,fido实例有一个实例变量,一个,@name,所以fido.instance_variables方法返回一个带有那个符号的数组。

更新

回答您在代码示例中的评论中提出的问题:

不,你的前两条评论不准确。这不是因为它没有方法,而是因为它没有实例变量。 fido实例确实有一个方法set_name方法。

您的第二条评论不准确,因为此处没有继承,fidoDog2的实例,因此一旦调用set_name方法,它就具有实例变量,因为@name方法初始化了set_name

关于eval的最终评论/问题仅仅是因为如果作者实际上只编写了fido.@name,那么代码本身就无法运行,他们希望它能够运行但是显示如果您在代码中写了fido.@name,那么由于语法错误,Ruby会退出并拒绝运行您的代码。

另一次更新

来自OP的另一个问题我想添加,虽然@name方法中存在set_name,但这个例子的真正意义在于,在set_name之前显示称@name变量尚未存在。在其他语言中,您可以预先定义所有实例变量,因此它们始终存在于该类的任何实例化对象中。

Ruby是一种更加动态的语言,因此在实际执行@name = a_name代码行之前,@name变量不存在,因此不会在fido.instance_variables中返回

即使调用该方法也是如此,但@name = a_name行未被执行,例如。

class Dog2
  def set_name a_name
    if false
      @name = a_name
    end
  end
end

fido = Dog2.new
fido.set_name "Fido"

fido.instance_variables # => []

希望有所帮助。

相关问题