ruby 在一个类中混合 attr_accessor 和 initialize 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16655915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:58:37  来源:igfitidea点击:

Intermingling attr_accessor and an initialize method in one class

rubyinitializationaccessor

提问by David

I see code like:

我看到这样的代码:

class Person
  def initialize(name)
    @name = name
  end
end

I understand this allows me to do things like person = Person.newand to use @nameelsewhere in my class like other methods. Then, I saw code like:

我明白这让我可以做类似的事情,person = Person.new@name像其他方法一样在我班级的其他地方使用。然后,我看到了如下代码:

class Person
  attr_accessor :name
end

...

person = Person.new
person.name = "David"

I'm just at a loss with these two methods mesh. What are the particular uses of def initialize(name)? I suppose attr_accessorallows me to read and write. That implies they are two separate methods. Yes? Want clarifications on def initializeand attr_accessorand how they mesh.

我只是对这两种方法网格不知所措。有什么特殊用途def initialize(name)?我想attr_accessor允许我阅读和写作。这意味着它们是两种不同的方法。是的?希望在澄清def initializeattr_accessor他们如何网状。

回答by Sergio Tulentsev

initializeand attr_accessorhave nothing to do with each other. attr_accessor :namecreates a couple of methods:

initialize并且attr_accessor彼此没有任何关系。attr_accessor :name创建几个方法:

def name
  @name
end

def name=(val)
  @name = val
end

If you want to set name upon object creation, you can do it in the initializer:

如果要在创建对象时设置名称,可以在初始化程序中进行:

def initialize(name)
  @name = name
  # or
  # self.name = name
end

But you don't have to do that. You can set name later, after creation.

但你不必这样做。创建后,您可以稍后设置名称。

p = Person.new
p.name = "David"
puts p.name # >> "David"

回答by Arup Rakshit

Here is the answer you are looking for Classes and methods. Read it carefully.

这是您正在寻找的答案Classes and methods。仔细阅读。

Here is a good documentation from the link:

这是链接中的一个很好的文档:

Classes and methods

类和方法

Now we are ready to create our very own Address class. Let's start simple. Let's start with an address that only contains the "street" field.

现在我们已准备好创建我们自己的 Address 类。让我们从简单的开始。让我们从一个只包含“街道”字段的地址开始。

This is how you define a class:

这是定义类的方式:

class Address
    def initialize(street)  
        @street = street 
    end
end

Let's go through this:

让我们来看看这个:

  • The class keyword defines a class.

  • By defining a method inside this class, we are associating it with this class.

  • The initialize method is what actually constructs the data structure. Every class must contain an initialize method.

  • class 关键字定义了一个类。

  • 通过在这个类中定义一个方法,我们将它与这个类相关联。

  • 初始化方法是实际构造数据结构的方法。每个类都必须包含一个 initialize 方法。

@street is an object variable. Similar to the keys of a hash. The @ sign distinguishes @street as an object variable. Every time you create an object of the class Address, this object will contain a @street variable.

@street 是一个对象变量。类似于散列的键。@ 符号将@street 区分为对象变量。每次创建类 Address 的对象时,该对象都会包含一个@street 变量。

Let's use this class to create an address object.

让我们使用这个类来创建一个地址对象。

address = Addres.new("23 St George St.")  

That's it. address is now an object of the class Address Reading the data in an object

就是这样。address 现在是 Address 类的对象 读取对象中的数据

Suppose that we want to read the data in the address object. To do this, we need to write a method that returns this data:

假设我们要读取地址对象中的数据。为此,我们需要编写一个返回此数据的方法:

class Address
    def initialize(street)   
        @street = street 
    end

    # Just return @street
    def street
        @street
    end
end

Now the method Address#street lets you read the street of the address. In irb:

现在,Address#street 方法可以让您读取地址所在的街道。在 irb 中:

>> address.street 
=> "23 St George St."

A property of an object, which is visible outside, is called an attribute. In this case, street is is an attribute. In particular, it is a readable attribute. Because this kind of attribute is very common, Ruby offers you a shortcut through the attr_reader keyword:

在外面可见的对象的属性称为属性。在这种情况下,街道是一个属性。特别是,它是一个可读的属性。因为这种属性很常见,Ruby 提供了一个通过 attr_reader 关键字的快捷方式:

class Address
    attr_reader :street
    def initialize(street)   
        @street = street 
    end
end

Changing the data in an object

更改对象中的数据

We can also define a method to change the data in an object.

我们还可以定义一个方法来更改对象中的数据。

class Address
    attr_reader :street
    def initialize(street)  
        @street = street 
    end
    def street=(street)
        @street = street
    end
end

Ruby is pretty smart in its use of the street= method:

Ruby 在使用 street= 方法方面非常聪明:

`address.street = "45 Main St`."

Notice that you can put spaces betten street and =. Now that we can change the address data, we can simplify the initialize method, and have it simply default the street to the empty string "".

请注意,您可以在 street 和 = 之间放置空格。现在我们可以更改地址数据,我们可以简化初始化方法,并将街道默认为空字符串“”。

class Address
    attr_reader :street
    def initialize
        @street = ""
    end
    def street=(street)
        @street = street  
    end
end

address = Address.new
address.street = "23 St George St."

This might not seem like much of a simplification, but when we add the city, state and zip fields, and more methods this will make the class definition a bit simpler.

这可能看起来不是很简单,但是当我们添加 city、state 和 zip 字段以及更多方法时,这将使类定义更简单一些。

Now, street is also a writable attribute. As before, you can declare it as such with attr_writer:

现在, street 也是一个可写的属性。和以前一样,您可以使用 attr_writer 声明它:

class Address
    attr_reader :street
    attr_writer :street  
    def initialize
        @street = ""
    end
end

Accessing data

访问数据

Very often, you have attributes that are both readable and writable attributes. Ruby lets you lump these together with attr_accessor. I guess these would be called "accessible attributes", but I have never seen them be called that.

很多时候,你有既可读又可写的属性。Ruby 允许您将它们与 attr_accessor 混为​​一谈。我想这些将被称为“可访问属性”,但我从未见过它们被称为。

class Address
    attr_accessor :street  
    def initialize
        @street = ""
    end
end

With this knowledge, it is now easy to define the entire addressbook structure. As it turns out, attr_accessor and friends all accept multiple arguments.

有了这些知识,现在可以轻松定义整个地址簿结构。事实证明,attr_accessor 和朋友都接受多个参数。

class Address
    attr_accessor :street, :city, :state, :zip  
    def initialize
        @street = @city = @state = @zip = ""
    end
end

回答by sawa

I think you consider initializeas a constructor. To be precise, it is not. The default constructor is the newmethod on the class, and initializeis called by that method. If you do not define initialize, you can still create an object with newbecause initializeis not the constructor itself. In that case, the default initializedoes nothing. If you do define initialize, then that is called right after the object creation.

我认为您认为initialize是构造函数。准确地说,并非如此。默认构造函数是new类上的方法,initialize并由该方法调用。如果你没有定义initialize,你仍然可以创建一个对象,new因为initialize它不是构造函数本身。在这种情况下,默认值initialize什么都不做。如果您确实定义了initialize,则在创建对象后立即调用它。

The statement @foo = ...and attr_accessor :fooare different. The former assigns a value to the instance variable @foo, whereas the latter lets you access @foovia methods fooand foo=. Without the latter, you can still access @fooby directly describing so.

的说法@foo = ...attr_accessor :foo是不同的。前者为实例变量赋值@foo,而后者允许您@foo通过方法foo和访问foo=。如果没有后者,您仍然可以@foo通过直接描述来访问。

回答by Aditya Aswal

Unlike C++,Java instance variables in Ruby are privateby default(partially as they can be accessed by using a.instance_variable_get :@x)

与 C++ 不同,Ruby 中的 Java 实例变量默认是私有的(部分原因是可以使用 a.instance_variable_get :@x 访问它们)

eg:

例如:

  class Dda
    def initialize task
        @task = task
        @done = false
    end
  end
item = Dda.new "Jogging" # This would call the initializer and task = Jogging would
be set for item
item.task # would give error as their is no function named task to access the instance
variable.

Although we have set the value to item but we won't be able to do anything with it as instace variables are private in ruby. code for getter:

虽然我们已经将值设置为 item 但我们将无法对它做任何事情,因为 instace 变量在 ruby​​ 中是私有的。吸气剂代码:

def task
  @task
end
#for getter
def task=task
   @task = task
end

Using getter would ensure that item.task returns it's value And using setter gives us the flexibility to provide values to instance variables at any time.

使用 getter 将确保 item.task 返回它的值。使用 setter 使我们可以灵活地随时为实例变量提供值。