@@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]
end
end
注:关于@name
这里,这是一个instance variable
,具体见笔记17.
到场学生名单
write code
- 这时候的self自然而言是
Student
这个类,代码里对应的就是self.add_student(name)
,到场学生分别是ABC
三人 :
# self is the class object-Student
Student.add_student("A")
Student.add_student("B")
Student.add_student("C")
run it and output
Welcome : A
Welcome : B
Welcome : C
开始提问
write code
- 老师提了3个问题,喊道A同学2次,喊道B同学一次,点名提问真是太刺激了!
#self is the instance of Student that's calling the method
ask1 = Student.new("A")
ask2 = Student.new("B")
ask3 = Student.new("A")
run it and output
This time : A
This time : B
This 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 : 2
B answered question ? times : 1
There 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