是一个引用类实例的实例变量吗?

时间:2017-03-22 21:01:42

标签: ruby-on-rails ruby

我很困惑,也会感激一些帮助。

我正在阅读Michael Hartl教程,最复杂的方面(对我来说)只是理解我认为语法上的不一致(我知道我在这方面做错了,而且它是&#39 ;只是我的感受)。

我目前在第8章,但是从前面的一个简单示例:

def show
  @user = User.find(params[:id])
end

另一个:

 def create
  @user = User.new(user_params)
  if @user.save
    log_in @user
    flash[:success] = "Welcome to the Sample App!"
    redirect_to @user
  else
    render 'new'
  end
end

据我了解实例变量,它们应该是对象或类实例的属性,例如:name,:email,:password_digest等。

在这些示例中,我们还没有为类编写初始化方法,因为我们只是生成了一个带有4/5列的迁移(与指定的属性相对应);据我所知,这次迁移中的列被Rails解释为类的实例的属性或实例变量(对象?)

@user或者为什么在此上下文中使用的实例变量是什么?它不是类的实例的属性(例如:name),而是看起来是类的实例的引用,占位符或表示?

n.b。我理解(好吧,初学者理解)上面代码的作用,即查询用户模型 - 也称为用户 - 来检索记录,但是我不明白为什么要将其分配给实例变量或在什么上下文中使用实例变量,即我认为它们用于为类的实例指定属性,而不是作为占位符操作或引用类的实例(包括其属性)。

编辑:我认为我的混淆来自用于指定属性的实例变量,并且根据下面Mark的定义,'作为所有的容器运行一个类的属性。'

以上示例似乎使用实例变量作为属性的容器,而我读过的其他示例使用实例变量来存储属性值。

本书前面的一个例子:

def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end

我想这两者都是?

1 个答案:

答案 0 :(得分:0)

来自rubyist.net

  

实例变量的名称以@开头,其范围仅限于自己引用的任何对象。两个不同的对象,即使它们属于同一个类,也允许它们的实例变量具有不同的值。

所以回答你的问题:是的,实例变量指的是类的实例,与类的属性不同。更准确地说,实例变量只是一个类的所有属性的容器(在本例中是User类)。每当您使用@user语法时,您都说要创建自己的用户实例,并为用户的属性设置单独的值,而不是另一个实例变量。

我可以像这样创建两个实例变量:

@user1 = User.new
@user2 = User.new

现在,我可以像这样单独为用户分配属性:

@user1.email = "test@exmample.com"
@user2.email = "anotheremail@example.com"

此用户的每个实例都是唯一的,这是实例变量背后的核心概念。

但是,对于rails,您在控制器中声明的任何实例变量都可以在相应的视图中访问,这就是您可以访问@user文件中的new.html.erb变量的原因。< / p>

修改

以下是您更新帖子的代码:

def initialize(attributes = {})
  @name = attributes[:name]
  @email = attributes[:email]
end

initialize方法实际上是在创建新对象时调用的方法。例如,如果我创建了一个新的用户对象,我就这样做:

@user = User.new

默认情况下,执行此操作时将调用initialize类的User方法。此外,您会注意到initialize方法采用一个名为attributes的参数。参数定义如下:

def initialize(attributes = {})

这意味着如果您将任何参数传递给new方法,那么这些参数将被传递到attributes参数。 = {}只是意味着如果您没有向新方法方法传递任何参数,attributes参数将默认为空白哈希值。

例如,我可以像这样初始化一个用户对象:

@user = User.new(name: "mark", email: "test@example.com")

nameemail参数将通过initialized哈希传递到attributes方法。那么,你的代码突然变得更有意义了。这一行:

@name = attributes[:name]

只需将您传递给new方法的名称指定为@user.name的值即可。所以从这个意义上说,上面的行很容易混淆,因为它似乎是为实例变量赋值,但它实际上只是在name个实例上赋值@user属性的值变量。

因此,一旦initialize方法返回,@user变量就可以访问您在initialize方法中指定的属性。

更多阅读: