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

@@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这个实例对象。

本篇以具体的用例为笔记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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值