红宝石示例中.self的用法是什么

bil*_*ill 1 ruby

我一直在读我的教科书,我们上了课,关键词self出现了。我一直在阅读有关tutorialpoint的一些教程,并且阅读了许多SO问题,但是由于某些原因,它只是没有点击我的“ ruby​​ self”,所以我决定自己修改一些示例

考虑

class Box
   # Initialize our class variables
   @@count = 0
   def initialize(w,h)
      # assign instance avriables
      @width, @height = w, h

      @@count += 1
   end

   def self.printCount()
      puts "Box count is : #@@count"
   end

end

# create two object
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)

# call class method to print box count
Box.printCount()
Run Code Online (Sandbox Code Playgroud)

如果self.printCount()方法中删除,为什么会出现错误?我知道self区分类变量和实例变量非常重要,就像我的示例@width,@height@@count

因此,我的想法是,由于我要修改类变量@@count,因此我要使用.self关键字,因为我要修改类变量。因此,每当要更改类变量时,都必须使用form def self.methodName

我的思维过程正确吗?

dav*_*000 5

您在此处使用两种方法:实例方法和类方法。如您所知,Ruby是一种面向对象的编程语言,因此一切都是对象。每个对象都有自己可以调用的方法。让我们看看你的代码

class Box
   # Initialize our class variables
   @@count = 0
   def initialize(w,h)
      # assign instance avriables
      @width, @height = w, h
      @@count += 1
   end

   def self.printCount()
      puts "Box count is : #@@count"
   end

end
Run Code Online (Sandbox Code Playgroud)

当使用创建方法时self.method_name,您将为类本身创建方法。因此,的对象Box具有称为的方法printCount()。这就是为什么您可以直接调用该方法的原因。

Box.printCount()
Run Code Online (Sandbox Code Playgroud)

但是,如果声明该类的新实例,则Box调用printCount()会导致错误。

box1 = Box.new(1,1)
box1.printCount() #=> undefined method `printCount'
Run Code Online (Sandbox Code Playgroud)

这是因为它box1是类的实例Box,并且该printCount方法只能由该类访问Box

如果删除self方法之前的printCount,它将成为实例方法,然后box1可以访问该方法,但该类Box则不能。

还有一些语义,Ruby使用蛇名作为方法名,所以printCount应该是print_count。这只是标准做法,并不真正影响代码的运行方式。

另外,您需要注意类变量,即@@count。它们的行为不像您在Ruby中所期望的那样。它不仅属于它所声明的类,它还是它的任何后代的一部分。

例如,假设我定义了一个新的类调用SmallBox并从继承Box

box1 = Box.new(1,1)
box1 = Box.new(1,1)
Run Code Online (Sandbox Code Playgroud)

现在,该计数应为2 Box。但是,如果您尝试@@count从我的新班级访问,

class SmallBox < Box
   p @@count
end
Run Code Online (Sandbox Code Playgroud)

这也将打印2

后代对class变量所做的任何更改都会更改其值。

例如,我声明了的实例SmallBox,该实例将加1 @@count。您可以查看是否检查了中的计数Box,它还添加了1。

small1 = SmallBox.new(1,1)

class SmallBox
    p @@count #=> 3
end

class Box 
    p @@count #=> 3
end
Run Code Online (Sandbox Code Playgroud)