Ruby类:初始化self和@variable

时间:2022-05-21 22:28:38

Can someone explain the difference between initializing "self" and having @variables when defining classes?

有人能解释在定义类时初始化“self”和使用@variables的区别吗?

Here's an example

这里有一个例子

class Child < Parent
  def initialize(self, stuff):
    self.stuff = stuff
    super()
  end
end

So in this case, wouldn't I be able to replace self.stuff with @stuff? What's the difference? Also, the super() just means whatever is in the Parent initialize method the Child should just inherit it right?

在这种情况下,我不能替换self。和@stuff东西吗?有什么区别呢?另外,super()只是表示父初始化方法中的任何东西,孩子应该继承它,对吗?

2 个解决方案

#1


38  

In general, no, self.stuff = stuff and @stuff = stuff are different. The former makes a method call to stuff= on the object, whereas the latter directly sets an instance variable. The former invokes a method which may be public (unless specifically declared private in the class), whereas the latter is always setting a private instance variable.

一般来说,自我。stuff = stuff和@stuff = stuff是不同的。前者对对象上的stuff=进行方法调用,而后者直接设置实例变量。前者调用的方法可能是公共的(除非类中明确声明为私有),而后者总是设置私有实例变量。

Usually, they look the same because it is common to define attr_accessor :stuff on classes. attr_accessor is roughly equivalent to the following:

通常,它们看起来是一样的,因为在类上定义attr_accessor:stuff是很常见的。attr_accessor大致等价于以下内容:

def stuff
  @stuff
end

def stuff=(s)
  @stuff = s
end

So in that case, they are functionally identical. However, it is possible to define the public interface to allow for different results and side-effects, which would make those two "assignments" clearly different:

在这种情况下,它们在功能上是相同的。但是,可以定义公共接口以允许不同的结果和副作用,这将使这两项“任务”明显不同:

def stuff
  @stuff_called += 1    # Keeps track of how often this is called, a side effect
  return @stuff
end

def stuff=(s)
  if s.nil?             # Validation, or other side effect. This is not triggered when setting the instance variable directly
    raise "Argument should not be nil"
  end
  @stuff = s
end

#2


6  

You actually can't use self.stuff= unless you specifically create an attr_writer for modifying that value.

你实际上不能使用self。stuff=除非您专门创建一个attr_writer来修改该值。

In fact, these are equivalent:

事实上,它们是等价的:

class Child
  attr_writer :stuff
end

class Child
  def stuff=(val)
    @stuff = val
  end
end

It is more common to use an attr_writer if that is the functionality you want, rather than the explicit method. But you will often use an explicit method if you want to perform extra error checking or change the way the assignment works.

如果attr_writer是您想要的功能,那么使用它比使用显式方法更常见。但是如果您想执行额外的错误检查或更改赋值的工作方式,您通常会使用显式方法。

To your question of when to use @stuff = and when to use self.stuff =, I would use the former if you only have simple assignments and if your class is simple, and would move towards the latter if your requirements might become more complicated. There are many other reasons too, but it's more a matter of style than anything else.

关于何时使用@stuff =以及何时使用self的问题。如果你只有简单的作业,如果你的课很简单,如果你的要求变得更复杂,我就用前者。还有很多其他的原因,但这更多的是风格的问题。

#1


38  

In general, no, self.stuff = stuff and @stuff = stuff are different. The former makes a method call to stuff= on the object, whereas the latter directly sets an instance variable. The former invokes a method which may be public (unless specifically declared private in the class), whereas the latter is always setting a private instance variable.

一般来说,自我。stuff = stuff和@stuff = stuff是不同的。前者对对象上的stuff=进行方法调用,而后者直接设置实例变量。前者调用的方法可能是公共的(除非类中明确声明为私有),而后者总是设置私有实例变量。

Usually, they look the same because it is common to define attr_accessor :stuff on classes. attr_accessor is roughly equivalent to the following:

通常,它们看起来是一样的,因为在类上定义attr_accessor:stuff是很常见的。attr_accessor大致等价于以下内容:

def stuff
  @stuff
end

def stuff=(s)
  @stuff = s
end

So in that case, they are functionally identical. However, it is possible to define the public interface to allow for different results and side-effects, which would make those two "assignments" clearly different:

在这种情况下,它们在功能上是相同的。但是,可以定义公共接口以允许不同的结果和副作用,这将使这两项“任务”明显不同:

def stuff
  @stuff_called += 1    # Keeps track of how often this is called, a side effect
  return @stuff
end

def stuff=(s)
  if s.nil?             # Validation, or other side effect. This is not triggered when setting the instance variable directly
    raise "Argument should not be nil"
  end
  @stuff = s
end

#2


6  

You actually can't use self.stuff= unless you specifically create an attr_writer for modifying that value.

你实际上不能使用self。stuff=除非您专门创建一个attr_writer来修改该值。

In fact, these are equivalent:

事实上,它们是等价的:

class Child
  attr_writer :stuff
end

class Child
  def stuff=(val)
    @stuff = val
  end
end

It is more common to use an attr_writer if that is the functionality you want, rather than the explicit method. But you will often use an explicit method if you want to perform extra error checking or change the way the assignment works.

如果attr_writer是您想要的功能,那么使用它比使用显式方法更常见。但是如果您想执行额外的错误检查或更改赋值的工作方式,您通常会使用显式方法。

To your question of when to use @stuff = and when to use self.stuff =, I would use the former if you only have simple assignments and if your class is simple, and would move towards the latter if your requirements might become more complicated. There are many other reasons too, but it's more a matter of style than anything else.

关于何时使用@stuff =以及何时使用self的问题。如果你只有简单的作业,如果你的课很简单,如果你的要求变得更复杂,我就用前者。还有很多其他的原因,但这更多的是风格的问题。