Ruby setters - 无论是由类创建(c)attr_accessor还是手动创建- 似乎是self.在类本身内访问时需要限定的唯一方法.这似乎使Ruby独自成为语言世界:
self/ this(像Perl,我认为是Javascript)self/ this是(C#,Java)self/ this(Ruby?)最好的比较是C#VS红宝石,因为这两种语言都支持这句法工作就像类的实例变量的访问方法:foo.x = y,y = foo.x.C#称它们为属性.
这是一个简单的例子; Ruby中的相同程序然后是C#:
class A
def qwerty; @q; end # manual getter
def qwerty=(value); @q = value; end # manual setter, but attr_accessor is same
def asdf; self.qwerty = 4; end # "self." is necessary in ruby?
def xxx; asdf; end # we can invoke nonsetters w/o "self." …Run Code Online (Sandbox Code Playgroud) 根据我对self关键字的理解,它只是引用了类的当前实例.这不是一直都是默认行为吗?例如,不是
self.var_one = method(args)相当于var_one = method(args)?
如果是这样那么自我的用途是什么?
在我的整个申请self.中,没有必要引用用户的名字.name工作良好.
为什么以下代码需要self按预期工作?
class User< ActiveRecord::Base
before_save :validate_name
def validate_name
if self.name.nil? || self.name.empty?
self.name= "Mr. No Name"
end
end
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我知道validates_presence_of可以用来阻止保存,但如果没有给出名字,我想保存默认值.
Rails 3.0.7.
这个方法:
def format_stations_and_date
from_station.titelize! if from_station.respond_to?(:titleize!)
to_station.titleize! if to_station.respond_to?(:titleize!)
if date.respond_to?(:to_date)
date = date.to_date
end
end
Run Code Online (Sandbox Code Playgroud)
如果date为nil ,则会出现此错误:
NoMethodError (You have a nil object when you didn't expect it!
The error occurred while evaluating nil.to_date):
app/models/schedule.rb:87:in `format_stations_and_date'
app/controllers/schedules_controller.rb:15:in `show'
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改date = date.to_date为self.date = self.date.to_date,该方法可以正常工作.
这是怎么回事?一般来说,我self什么时候写?
编辑:这与问题无关,但请注意,没有"标题!" 方法.
例如,如果我们
def c=(foo)
p "hello"
end
c = 3
c=(3)
Run Code Online (Sandbox Code Playgroud)
并且不打印"你好".我知道它可以被调用,self.c = 3但为什么呢?以及在其他方面可以调用它?
我试图调用我的一个类属性编写器,但由于某种原因它永远不会被调用.这里有一些代码可以让我更清楚:
class Test
attr_reader :test
def test=(val)
puts 'Called'
@test = val
end
def set_it(val)
test = val
end
end
obj = Test.new
obj.set_it 5
puts obj.test
=> nil
Run Code Online (Sandbox Code Playgroud)
最后的puts语句输出'nil'.向test =添加一个调试语句表明它永远不会被调用.我究竟做错了什么?
更新
我部分地重写了这个问题,因为当我写这个问题时我并没有真正理解这个问题.所以这个问题现在更加普遍.
我有User与之has_many关系的模型UserFilter.UserFilter与...有belongs关系User.
在User模型中,我有一个名为的方法 update_user_filters(filter_params_array)
这种方法user_filters像这样修改
def update_user_filters(filter_params_array)
new_filters = []
old_filter = user_filters
filters_params_array.each do |filter_params|
if filter_params[:id].blank? #if the filter does not yet exist
new_filters << UserFilter.new(filter_params)
end
end
user_filters = new_filters
end
Run Code Online (Sandbox Code Playgroud)
这user_filters会将其设置为预期值,但在保存时不会更新user_filters数据库中的值.
但是,如果我将分配更改为以下内容,则确实如此.有人可以解释为什么会这样吗?
self.user_filters = new_filters
Run Code Online (Sandbox Code Playgroud)
请注意,当我user_filters在模型中首次引用时,在db中执行select操作,因此我不确定此本地方法在使用self和不使用时的工作方式不同self