[Ruby笔记]28.Ruby @@class_variables 类变量 vs @instance_variable 实例变量

来源:互联网 发布:淘宝店铺下载 编辑:程序博客网 时间:2024/05/03 08:56

@@class_variables

TestCase

  • 想象这样一个场景,一次小班授课,参加的学生有A B C 三人 ,这时候老师开始提问了,我们使用类Student 记录 :
    • 到场的学生名单;
    • 每人答题次数;
    • 老师总的提问次数

Code

Class Student 类

  • @@names存着学生名单的数组 ;
  • @@answers存着每个学生答题次数的哈希表 ;
  • @@total_answers存着老师总的提问次数的class variable
  • attr_reader :name存着某个学生名字的instance variable
class Student    @@names = [] # array    @@answers = {} # hash    @@total_answers = 0    attr_reader :name    def self.total_answers        @@total_answers    end    def self.add_student(name)        unless @@names.include?(name)            puts "Welcome : #{name}"            @@names << name # << array - append operator            @@answers[name] = 0        end    end    def initialize(name)        if @@names.include?(name)            puts "This time : #{name}"            @name = name            @@answers[name] += 1            @@total_answers += 1        else raise "No such person : #{name}"        end    end    def answer        @@answers[self.name]    endend

注:关于@name 这里,这是一个instance variable ,具体见笔记17.

到场学生名单

write code

  • 这时候的self自然而言是Student这个类,代码里对应的就是 self.add_student(name) ,到场学生分别是ABC三人 :
# self is the class object-StudentStudent.add_student("A")Student.add_student("B")Student.add_student("C")

run it and output

Welcome : AWelcome : BWelcome : C

开始提问

write code

  • 老师提了3个问题,喊道A同学2次,喊道B同学一次,点名提问真是太刺激了!
#self is the instance of Student that's calling the methodask1 = Student.new("A")ask2 = Student.new("B")ask3 = Student.new("A")

run it and output

This time : AThis time : BThis time : A

记录次数的显示

write code

  • 这时候self就变成每个ask,可以是ask1也可以是ask2或者ask3
  • 最有趣的部分就在于此aks1以及ask3 这两次问题都是A来回答的,因此无论是用ask1.answer还是ask3.answer都会得到A的答题次数,那就是2次;
puts "A answered question ? times : #{ask1.answer}"# puts "A answered question ? times : #{ask3.answer}"puts "B answered question ? times : #{ask2.answer}"puts " "puts "There are ? total answers : #{Student.total_answers}"
  • 那是因为,回到class Student 的代码里,这时候的self是某个ask,但是无论是aks1还是ask3,它们的name都是A,所以无论是ask1还是ask3调用answer的时候都会得到A的答题次数 :
def answer    @@answers[self.name]end

run it and output

A answered question ? times : 2B answered question ? times : 1There are ? total answers : 3

如果喊错人名字了呢?

write code

  • 没有名字是D的学生,因此根据实现代码里的raise语句,程序会报错:
ask4 = Student.new("D")

run it and output

stu.rb:25:in `initialize': No such person : D (RuntimeError)        from stu.rb:57:in `new'        from stu.rb:57:in `<main>'

note

  • self 在做 Student.add_student("A") 时,是 Student这个类。
  • self 在做 ask1 = Student.new("A") 时,是 ask1这个实例对象。

link

本篇以具体的用例为笔记23的补充,此时回顾温习甚佳。

reference

《The Well-Grounded Rubyist, Second Edition》
5.2.5. Class variable syntax, scope, and visibility
(https://www.manning.com/books/the-well-grounded-rubyist-second-edition)

おやすみぃ~  ∧∧[(^-^*)] ┌∪─∪┐ │◆◇◆│ │◇◆◇│ └───┘http://emoji.vis.ne.jp/oyasumi36.htm
0 0
原创粉丝点击