在Ruby中访问Class变量

时间:2018-07-19 15:13:52

标签: ruby

我有一个数组用作以下结构的输入:

> student_data = [
>     {
>         :first_name => "James",
>         :last_name => "Smith",
>         :date_of_birth => { :day => 5, :month => 10, :year => 1994 },
>         :study_results => {
>             :CAR => nil,
>             :PR1 => 1,
>             :MA1 => 1,
>             :BEN => 2,
>             :SDP => nil
>         }
>     }, ...]

我正在用代码创建Student类的实例:

student_data.each do |student|
  UC::Student.new(student[:first_name], student[:last_name], student[:date_of_birth], student[:study_results])
end

该类如下:

    require_relative("person.rb")
module UC
  class Student < Person
    include Comparable
    @@students = []
    def initialize(first_name, last_name, date_of_birth, study_results)
      @date_of_birth = date_of_birth
      @study_results = study_results
      super(first_name, last_name)
      @@students << self
    end
    def <=>(other) 
      return last_name_comparison = @last_name <=> other.last_name unless last_name_comparison == 0
      return first_name_comparison = @first_name <=> other.first_name unless first_name_comparison == 0
      return date_of_birth_comparison = @date_of_birth <=> other.date_of_birth
    end
    def list_study_results
      return @study_results
    end
  end
end

现在,例如,如果我想使用方法list_study_results,如何从@@ students访问实例?

其他问题,在方法<=>中,我将调用了该方法的实例的实例变量(@last_name,...)与其他实例的实例变量进行比较。为什么我必须使用other.last_name而不是other。@ last_name?

1 个答案:

答案 0 :(得分:2)

当您定义或访问以@开头的变量时,您正在创建/访问实例变量。将实例变量视为学生的“一部分”。学生的名字,姓氏,出生日期等。

关于实例变量的规则之一是只能从实例的内部中访问它们。因此,如果您在特定学生内部的方法中,则只能从该学生读取实例变量。在OOP编程中,这通常称为封装-您可以控制有关公开学生的哪些信息,因此您无法从学生A的上下文访问有关学生B的信息。

您可以做的是定义一个公共界面,该界面可让您从“外部”访问有关学生的信息。您可以使用常规方法执行此操作:

def first_name
  @first_name
end

或Ruby为您提供了执行相同操作的快捷方式:

attr_reader :first_name

对于它的价值,即使在一个类中,使用这些阅读器通常也是最佳实践。

您已经通过list_study_results将学习结果定义为班级公共界面的一部分。因此,要让任何学生访问它,只需致电:

student.list_study_results

@@students.first.list_study_results

为了简化操作,通常将公用接口的名称与内部变量的名称相同,因此您可以考虑将list_study_results重命名为study_results