`

self.与@的区别——别被原有的思维方式误导

阅读更多
最近在学习Rails时把先前在Java中的一些习惯性思维带了过了,结果在遇到self.与@时被这种思维方式给误导了。

遇到这个问题是在使用AcriveRecord时,在修改或者新增记录时需要添加时间戳。首先使用self.posted_at=Time.now来修改字段,一切正常。后来想到在哪篇文章中好像说过self.与Java中的this差不多,这样就不自觉的把posted_at当作了实例变量处理,试了一下用@posted_at=Time.now,没有出错,但是记录的时间并没有被更新。

起初想到书上说ActiveRecord在第一次访问那个类时,将根据表结构信息,自动添加列到实例变量并增加对这些变量的访问器。似乎没有错呀,既然是实例变量不就是@吗?

用instance_values查看才恍然大悟,@attributes这个实例变量保存了各个字段的值。ActiveRecord在初始化这一个类时,添加的实例变量并不是一个数据库字段对应于一个实例变量,而是放到了@atributes里。然后添加了对各个字段的访问器。通过methods方法可以查看实例中的所有方法,可以看到有posted和posted=这两个访问器方法。

self.!=this
self.是方法调用,而不是直接访问实例变量。

从这个错误中,我也清楚了下面三种写法的区别:
1. self.id=        调用id方法。
2. @id=            直接访问实例变量
3. id=                如果前面不加self.,解释器将认为你要给一个局部变量赋值,而不会认为你是要调用id=这个方法修字段id的数据。
分享到:
评论
9 楼 hideto 2007-06-30  
在set_name里面调用name=,不会调用obj.name=,而是把name当作local变量,我理解你的意思了gigix,笨啊
8 楼 hideto 2007-06-30  
set_name方法对name作修改,而不是对@name做修改,当然结果是@name不变

所以说,不同语言不同语法而已
7 楼 gigix 2007-06-30  
hideto 写道
gigix 写道
呵呵,另一个有趣的是
@name = ""
attr_writer :name
def set_name(input_name)
  name = input_name 
end

调用set_name不会对@name设值,因为Ruby认为set_name里的name是一个局部变量……

name和@name本来就不一样

attr_writer :name
这句会创建name=方法的
6 楼 hideto 2007-06-30  
<br/>
<strong>Jamsa 写道:</strong><br/>
<div class='quote_div'>最近在学习Rails时把先前在Java中的一些习惯性思维带了过了,结果在遇到self.与@时被这种思维方式给误导了。<br/>
<br/>
遇到这个问题是在使用AcriveRecord时,在修改或者新增记录时需要添加时间戳。首先使用self.posted_at=Time.now来修改字段,一切正常。后来想到在哪篇文章中好像说过self.与Java中的this差不多,这样就不自觉的把posted_at当作了实例变量处理,试了一下用@posted_at=Time.now,没有出错,但是记录的时间并没有被更新。<br/>
<br/>
起初想到书上说ActiveRecord在第一次访问那个类时,将根据表结构信息,自动添加列到实例变量并增加对这些变量的访问器。似乎没有错呀,既然是实例变量不就是@吗?<br/>
<br/>
用instance_values查看才恍然大悟,@attributes这个实例变量保存了各个字段的值。ActiveRecord在初始化这一个类时,添加的实例变量并不是一个数据库字段对应于一个实例变量,而是放到了@atributes里。然后添加了对各个字段的访问器。通过methods方法可以查看实例中的所有方法,可以看到有posted和posted=这两个访问器方法。<br/>
<br/>
self.!=this<br/>
self.是方法调用,而不是直接访问实例变量。<br/>
<br/>
从这个错误中,我也清楚了下面三种写法的区别:<br/>
1. self.id=        调用id方法。<br/>
2. @id=            直接访问实例变量<br/>
3. id=                如果前面不加self.,解释器将认为你要给一个局部变量赋值,而不会认为你是要调用id=这个方法修字段id的数据。</div>
<br/>
<br/>
只是不同语言的语法不一样罢了,和思维方式没什么关系
5 楼 hideto 2007-06-30  
gigix 写道
呵呵,另一个有趣的是
@name = ""
attr_writer :name
def set_name(input_name)
  name = input_name 
end

调用set_name不会对@name设值,因为Ruby认为set_name里的name是一个局部变量……

name和@name本来就不一样
4 楼 笨笨狗 2007-06-28  
这些问题,R4R里面就有讲的,此书虽然罗嗦,但是还不错
3 楼 logo 2007-06-28  
楼主对self的理解不准确。self在不同的作用域具有不同的含义,《ruby for rails》专门有一章内容就是讲self的。

具体在一个类的一个方法内部使用self,那么这个self代表该类的当前对象实例,因此:self.id= 就是调用当前该类对象实例的id=()方法。此时一定要加self,否则ruby解析器优先把id解析为一个方法内部的局部变量。

2 楼 gigix 2007-06-28  
呵呵,另一个有趣的是
@name = ""
attr_writer :name
def set_name(input_name)
  name = input_name 
end

调用set_name不会对@name设值,因为Ruby认为set_name里的name是一个局部变量……
1 楼 rainchen 2007-06-28  
"在修改或者新增记录时需要添加时间戳"

针对这个问题,
你只需增加两个字段created_at和updated_at,类型为:datetime
无需其他设置,就能自动达到你的要求了

至于如何转化为精确的时间戳,请其他达人解答

更多魔术字段见:
http://wiki.rubyonrails.com/rails/pages/MagicFieldNames

相关推荐

    卡尔曼滤波算法的Python实现.zip

    self.P = self.F @ self.P @ self.F.T + self.Q def update(self, z): y = z - self.H @ self.x S = self.H @ self.P @ self.H.T + self.R K = self.P @ self.H.T @ np.linalg.inv(S) self.x = self.x + K @ ...

    Reachability—Master

    self.blockLabel.text = @"Not Fired Yet"; self.notificationLabel.text = @"Not Fired Yet"; self.localWifiblockLabel.text = @"Not Fired Yet"; self.localWifinotificationLabel.text = @"Not Fired Yet"; ...

    CAJViewer 7.2.self.exe PC

    CAJViewer 7.2.self.exe 用于 PC 上, 修正或增加了以下功能: 1.增加工具书版本,添加了屏幕取词功能。 2.更新CAJAX插件到最新版。 3.增加CAJAX插件对Firefox、Chrome、Safari等浏览器的支持。 4.修正了安装时...

    基于iOS开发

    [self addObserver:self forKeyPath:@"isRecording" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; [self addObserver:self forKeyPath:@"isPlaying" options:...

    python银行系统实现

    本文实例为大家分享了python实现银行系统的具体代码,供大家参考,具体内容如下 1、admin.py 定义管理员信息和主界面显示 #!/usr/bin/env python # coding:UTF-8 @version: python3.x ... self.name

    init和 dealloc中 self.xx的使用注意

    然而,关于在`init`和`dealloc`中使用`self.xx`与`_xx`的注意事项,存在一些潜在的风险和最佳实践。下面将详细解释这些概念,并阐述为什么应该避免在这些特定情境下使用`self.xx`。 首先,我们来了解`init`方法。当...

    CAJViewer 7.0.2.self.exe阅览器

    CAJViewer 7.0.2.self.exe阅览器,下载供大家使用。

    地图个人开发笔记和Demo

    1.OpenLayers 例子 —— 1.1 OlMap 基础类 —— 1.2 openlayers 实例化地图 —— 1.3 openlayers地图OSM形式 ...4.self-map源代码 —— 4.1 二维效果例子汇总图 —— 4.2 三维效果 —— 4.3 源代码下载

    深度学习基础 —— 构建基于 Transformer 的自然语言处理应用.pdf

    ### 深度学习基础 —— 构建基于 Transformer 的自然语言处理应用 #### 一、自然语言处理的发展与重要性 在过去十年间,自然语言处理(Natural Language Processing, NLP)的应用取得了巨大的进步,其影响力遍及各行...

    python数据加密的几种方式(csdn)————程序.pdf

    根据提供的文件信息,本文将详细解析Python中几种常见的数据加密方式。主要聚焦于AES加密算法的不同模式,包括ECB(电子密码本模式)、CFB(密码反馈模式)以及CBC(密码块链接模式)。此外,还会涉及Base64编码在...

    Self.less.2015.1080p 字幕

    Self.less.2015.1080p 字幕

    用 Python 从头实现一个神经网络(附代码)

    最后,我们可以使用测试集评估神经网络的性能,通过计算预测值与实际值之间的误差或准确率。 ```python test_errors = [] for inputs, targets in test_data: outputs = nn.forward_propagation(inputs) test_...

    python代码——弹球

    self.canvas.move(self.id,245,100) starts=[-3,-2,-1,1,2,3] random.shuffle(starts) self.x=starts[0] self.y=-3 self.canvas_height=self.canvas.winfo_height() self.canvas_width=self.canvas.winfo_...

    CAJViewer 7.0.2.self.part1.rar

    CAJViewer 7.0.2.self.part1.rarCAJViewer 7.0.2.self.part1.rar

    iOS长按按钮

    [self.button addTarget:self action:@selector(buttonTouchUpInside) forControlEvents:UIControlEventTouchUpInside]; [self.button addTarget:self action:@selector(buttonTouchUpOutside) forControlEvents:...

    PyQt5 控件字体样式等设置的实现

    在PyQt5中,可以通过多种方式来设置控件的字体样式。以下是一些常见的设置方法及其应用场景: 1. **设置文本标签** (`QLabel`) - **居中文本**: ```python self.headLabel.setAlignment(Qt.AlignCenter) ``` ...

    CAJViewer7.2.self.exe

    CAJViewer7.2.self.exe阅读器

    栈的实现——python

    ### 栈的实现——Python #### 一、栈的基本概念 栈(Stack)是一种非常重要的数据结构,在计算机科学中有着广泛的应用。它是一种特殊的线性表,只允许在一端进行插入或删除操作,遵循“后进先出”(Last In, First...

    CAJViewer 7.3.139.self.exe

    caj

    Microsoft.Press.MCTS.Self.Paced.Training.Kit.Exam.70-685.Mar.2010.rar

    Microsoft.Press.MCTS.Self.Paced.Training.Kit.Exam.70-685.Mar.2010.rar

Global site tag (gtag.js) - Google Analytics