Ruby有这种方便易用的方法来使用像这样的键来共享实例变量
attr_accessor :var
attr_reader :var
attr_writer :var
Run Code Online (Sandbox Code Playgroud)
为什么我会选择attr_reader或者attr_writer我可以简单地使用attr_accessor?有没有像表演(我怀疑)?我想有一个原因,否则他们就不会有这样的钥匙.
一般来说,如何获取对字符串中名称的对象的引用?
更具体地说,我有一个参数名称列表(成员变量 - 动态构建,所以我不能直接引用它们).
每个参数都是一个也有from_s方法的对象.
我想做类似以下的事情(当然这不起作用......):
define_method(:from_s) do | arg |
@ordered_parameter_names.each do | param |
instance_eval "field_ref = @#{param}"
field_ref.from_s(param)
end
end
Run Code Online (Sandbox Code Playgroud) 我有一个与名为'Order'的模型相关联的现有表单,但我想添加新的表单字段,以捕获要在第三方支付网关上处理的信用卡信息,如名称,cc号码等.
但由于我不想在我们的数据库中保存CC信息,因此我的订单表中没有相应的列.在提交表单时,这会给我一个错误,即那些信用卡输入字段不是订单模型的"部分".
什么时候在Rails模型中使用attr_reader/ attr_writer/ attr_accessor?
我刚开始学习ruby,我没有看到an @instace_variable和声明使用的属性之间的区别attr_accessor.
以下两个类有什么区别:
class MyClass
@variable1
end
Run Code Online (Sandbox Code Playgroud)
和
class MyClass
attr_accessor :variable1
end
Run Code Online (Sandbox Code Playgroud)
我在网上搜索了很多教程,每个人都使用不同的符号,是否需要对ruby版本做任何事情?我还搜索了StackOverflow中的几个旧线程
但我仍然无法弄清楚什么是最好的使用方法.
最近我一直在阅读"Ruby中的实用面向对象设计",我注意到最好的做法之一是使用访问器方法而不是直接抓取@instance_variable.例如:
class Foo
attr_accessor :bar
def initialize(my_argument)
@bar = my_argument
end
# bad
# def lorem_ipsum
# @bar * 999
# end
# good
def lorem_ipsum
bar * 999
end
end
Run Code Online (Sandbox Code Playgroud)
将事情保持干燥是有道理的,并且,如果我需要@bar在实际获取其价值之前以某种方式处理.但是,我注意到该initialize方法@bar直接设置实例变量的值:
class Foo
attr_accessor :bar
def initialize(my_argument)
@bar = my_argument #<-- why isn't self.bar = my_argument used here?
end
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?是不是应该使用setter方法而不是直接使用=运算符来设置实例变量的值?
ActiveRecord似乎以不同于attr_accessor的方式定义实例方法.
attr_accessor似乎没有为我新定义的属性定义超级方法:
class SomeClass
attr_accessor :some_attribute
def some_attribute
super
end
end
>> some_class = SomeClass.new
>> some_class.some_attribute
NoMethodError: super: no superclass method `some_attribute' for..
Run Code Online (Sandbox Code Playgroud)
而ActiveRecord肯定定义了一个超级方法:
class SomeClass < ActiveRecord::Base
# some_attribute is now a column in our database
def some_attribute
super
end
end
>> some_class = SomeClass.new
>> some_class.some_attribute
nil
Run Code Online (Sandbox Code Playgroud)
两者之间的区别在哪里?有没有办法让attr_accessor定义一个超级方法?
编辑:
我仍然不知道ActiveRecord如何定义它的方法,但我知道attr_accessor是如何做到的.而不是super我可以使用,@some_attribute因为它将值存储在同名的全局变量中:https://stackoverflow.com/a/4371458/586000
我看到这段代码:
# filename: play.rb
class A
attr_reader :a
def initialize(num)
@a=num # I have to use @ here
end
def m1
p "---"
p @a
p a
end
end
obj = A.new(1)
obj.m1
Run Code Online (Sandbox Code Playgroud)
我得到了输出
$ ruby play.rb
"---"
1
1
Run Code Online (Sandbox Code Playgroud)
如您所见,我可以在方法中将其a称为@a或两者都起作用。am1
什么时候以及为什么应该使用哪个?
在以下示例中,我不了解attr_reader或这样的关键字property:
class Voiture
attr_reader :name
attr_writer :name
property :id, Serial
property :name, String
property :completed_at, DateTime
end
Run Code Online (Sandbox Code Playgroud)
它们如何工作?如何创建自己的?它们是功能,方法吗?
class MyClass
mymagickstuff :hello
end
Run Code Online (Sandbox Code Playgroud) 我被教过用声明我的实例变量def initialize。我一直觉得我只能在我的initialize方法中声明实例变量。
但是,我@foo在initialize方法之外声明了一个实例变量,并使其按预期工作:
class FooBar
def initialize(bar)
@bar = bar
end
def foo_as_instance_var
@foo = @bar.split(' ')
@foo
end
end
x = "something wicked this way comes"
y = FooBar.new(x)
puts y.foo_as_instance_var
Run Code Online (Sandbox Code Playgroud)
为什么我可以在initialize方法外部声明实例变量?由于我可以在任何方法中声明实例变量,因此关于在哪里声明实例变量(即在中声明它们initialize)是否应该遵循最佳实践规则?