Ruby中的attr_访问器是什么?
我很难理解Ruby中的Ruby中的attr_访问器是什么?,ruby,Ruby,我很难理解Ruby中的attr\u访问器 有人能给我解释一下吗?基本上,他们伪造了可公开访问的数据属性,而Ruby没有这些属性。只是一种方法。(该链接应提供有关其工作原理的更多信息-查看生成的方法对,教程应向您展示如何使用它。) >技巧是类< /C> >不是Ruby中的定义(它是C++语言和java语言中的“一个定义”),但它是一个表达式。在这个求值过程中,调用attr\u访问器方法,然后修改当前类-记住隐式接收者:self.attr\u访问器,其中self是此时的“打开”类对象 对属性访问器
attr\u访问器
有人能给我解释一下吗?基本上,他们伪造了可公开访问的数据属性,而Ruby没有这些属性。只是一种方法。(该链接应提供有关其工作原理的更多信息-查看生成的方法对,教程应向您展示如何使用它。)
<> >技巧是类< /C> >不是Ruby中的定义(它是C++语言和java语言中的“一个定义”),但它是一个表达式。在这个求值过程中,调用attr\u访问器
方法,然后修改当前类-记住隐式接收者:self.attr\u访问器
,其中self
是此时的“打开”类对象
对属性访问器和朋友的需求是:
Ruby和Smalltalk一样,不允许在对象的methods1之外访问实例变量。也就是说,实例变量不能以x.y
的形式访问,这在Java甚至Python中都很常见。在Ruby中,y始终被视为要发送的消息(或“要调用的方法”)。因此,attr.*
方法创建包装器,通过动态创建的方法代理实例@variable
访问
样板很烂
希望这能澄清一些小细节。快乐编码
1严格来说,这不是真的,确实存在,但对“public instance variable”访问没有语法支持。attr\u accessor
非常简单:
attr_accessor :foo
是以下各项的快捷方式:
def foo=(val)
@foo = val
end
def foo
@foo
end
它只是一个对象的getter/setter,它只是一个为实例变量定义getter和setter方法的方法。实施的一个例子是:
def self.attr_accessor(*names)
names.each do |name|
define_method(name) {instance_variable_get("@#{name}")} # This is the getter
define_method("#{name}=") {|arg| instance_variable_set("@#{name}", arg)} # This is the setter
end
end
attr\u accessor
只是一种方法(如@pst所述)。它所做的是为您创建更多的方法
所以这里的代码是:
class Foo
attr_accessor :bar
end
等同于此代码:
class Foo
def bar
@bar
end
def bar=( new_value )
@bar = new_value
end
end
您可以自己用Ruby编写这种方法:
class Module
def var( method_name )
inst_variable_name = "@#{method_name}".to_sym
define_method method_name do
instance_variable_get inst_variable_name
end
define_method "#{method_name}=" do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
class Foo
var :bar
end
f = Foo.new
p f.bar #=> nil
f.bar = 42
p f.bar #=> 42
假设您有一个classPerson
class Person
end
person = Person.new
person.name # => no method error
显然,我们从未定义过方法名称。让我们这样做吧
class Person
def name
@name # simply returning an instance variable @name
end
end
person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
啊哈,我们可以读名字,但这并不意味着我们可以指定名字。这是两种不同的方法。前者称为读者,后者称为作者。我们还没有创造作家,所以让我们这样做吧
class Person
def name
@name # simply returning an instance variable @name
end
end
person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
太棒了。现在我们可以使用reader和writer方法编写和读取实例变量@name
。除了,这是如此频繁,为什么每次都要浪费时间写这些方法呢?我们可以做得更容易
class Person
attr_reader :name
attr_writer :name
end
即使这样也会重复。当您需要读写器时,只需使用访问器
class Person
attr_accessor :name
end
person = Person.new
person.name = "Dennis"
person.name # => "Dennis"
同样的道理!猜猜看:person对象中的实例变量@name
将被设置为与手动设置时一样,因此您可以在其他方法中使用它
class Person
attr_accessor :name
def greeting
"Hello #{@name}"
end
end
person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"
就这样。为了了解attr\u reader
、attr\u writer
和attr\u accessor
方法实际上是如何为您生成方法的,请阅读其他答案、书籍和ruby文档 简单地attr accessor
为指定属性创建getter
和setter
方法我认为让新rubyist/程序员(像我一样)感到困惑的部分原因是:
“为什么我不能告诉实例它有任何给定的属性(例如名称),然后一下子给该属性一个值?”
更一般化一点,但对我来说,这就是它的作用:
鉴于:
class Person
end
我们还没有将“人”定义为具有名称或任何其他属性的事物
因此,如果我们:
baby = Person.new
…试着给他们起个名字
baby.name = "Ruth"
我们得到一个错误,因为在Rubyland中,对象的Person类不是与“名称”相关联或能够具有“名称”的东西。。。然而
但是我们可以使用任何给定的方法(参见前面的答案)来表示,“Person类(baby
)的实例现在可以有一个名为“name”的属性,因此我们不仅有一种获取和设置该名称的语法方法,而且这样做对我们来说是有意义的。”
再一次,从稍微不同和更一般的角度回答这个问题,但我希望这有助于下一个找到这条线索的类Person实例。简单地说,它将为类定义一个setter和getter
注意
attr_reader :v is equivalant to
def v
@v
end
attr_writer :v is equivalant to
def v=(value)
@v=value
end
所以
定义类的setter和getter是等效的。如果您熟悉OOP概念,则必须熟悉getter和setter方法。
attr_访问器在Ruby中也做同样的事情
一般情况下的接受者和接受者
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"
class Person
attr_accessor :name
end
person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"
设置器方法
def name=(val)
@name = val
end
Getter方法
def name
@name
end
Ruby中的Getter和Setter方法
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"
class Person
attr_accessor :name
end
person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"
定义此模块的命名属性,其中名称为symbol.id2name,创建实例变量(@name)和相应的访问方法来读取它。还创建一个名为name=的方法来设置属性
module Mod
attr_accessor(:one, :two)
end
Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
我也面临着这个问题,并对这个问题写了一个有点长的答案。关于这一点已经有了一些很好的答案,但任何想要进一步澄清的人,我希望我的答案能有所帮助
初始化方法
Initialize允许您在创建实例时为对象的实例设置数据,而不必在每次创建类的新实例时在代码中的单独一行上设置数据
class Person
def initialize(name)
@name = name
end
def greeting
"Hello #{@name}"
end
end
person = Person.new("Denis")
puts person.greeting
在上面的代码中,我们使用initialize方法通过initialize中的参数传递Dennis来设置名称“Denis”。如果我们想在不使用initialize方法的情况下设置名称,我们可以这样做:
class Person
attr_accessor :name
# def initialize(name)
# @name = name
# end
def greeting
"Hello #{name}"
end
end
person = Person.new
person.name = "Dennis"
puts person.greeting
def name
"Fido"
end
在上面的代码中,我们通过使用person.name调用attr_accessor setter方法来设置名称,而不是在初始化对象时设置值
两种“方法”
class Item
attr_reader :item_name
def initialize(item_name)
@item_name = item_name
end
end
item = Item.new("TV")
puts item.item_name
class Car
def initialize
@wheels = 4 # This is an instance variable
end
end
c = Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
class Car
def wheels # getter method
@wheels
end
def wheels=(val) # setter method
@wheels = val
end
end
f = Car.new
f.wheels = 4 # The setter method was invoked
f.wheels # The getter method was invoked
# Output: => 4
class Car
attr_accessor :wheels
end
f = Car.new
f.wheels = 4
f.wheels # Output: => 4
class BankAccount
def initialize( account_owner )
@owner = account_owner
@balance = 0
end
def deposit( amount )
@balance = @balance + amount
end
def withdraw( amount )
@balance = @balance - amount
end
end
$ bankie = BankAccout.new("Iggy")
$ bankie
$ bankie.deposit(100)
$ bankie.withdraw(5)
$ bankie.owner #undefined method `owner'...
$ bankie.balance #undefined method `balance'...
$ bankie.balance
$ bankie.owner
class Foo
attr_accessor 'myvar'
def initialize
@myvar = "A"
myvar = "B"
puts @myvar # A
puts myvar # B - myvar declared above overrides myvar method
end
def test
puts @myvar # A
puts myvar # A - coming from myvar accessor
myvar = "C" # local myvar overrides accessor
puts @myvar # A
puts myvar # C
send "myvar=", "E" # not running "myvar =", but instead calls setter for @myvar
puts @myvar # E
puts myvar # C
end
end
class Nameable
def self.named(whatvalue)
define_method :name do whatvalue end
end
end
class Dog < Nameable
named "Fido"
end
def name
"Fido"
end
puts Dog.new.name #=> Fido