在Ruby中创建域模型,将学生添加到学校名单中

时间:2017-02-09 04:02:18

标签: ruby model

您应该可以通过调用add_student方法将学生添加到学校,并为学生提供学生姓名和成绩的参数。

让我们说我们正在添加学生" AC Slater"等级9.如果名册已经有9级钥匙,我们就可以将AC Slater推入9级钥匙所指向的阵列中。否则,我们需要先创建9级密钥并将其指向空数组。但是,如果我们在已经存在9级密钥的情况下,我们将通过创建9的密钥并将其设置为等于空数组来擦除其当前内容!

所需行为:

school.add_student("AC Slater", 9)
school.add_student("Kelly Kapowski", 10)
school.add_student("Screech", 11)
school.roster
# => {9 => ["Zach Morris", "AC Slater"], 10 => ["Kelly Kapowski"], 11     => ["Screech"]}

到目前为止我所拥有的:

class School
  attr_accessor :roster, :student_name, :school_name
  def initialize(school_name)
    @school_name = school_name
    @roster = {}
  end

  def add_student(student_name, grade)
    if @roster[grade] == true
      @roster[grade] << student_name
    else
      @roster[grade] = []
      @roster[grade] << student_name
    end
  end

end

1 个答案:

答案 0 :(得分:1)

==6841== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60040000e000 at pc 0x400eb5 bp 0x7fff3d5302c0 sp 0x7fff3d5302b0 READ of size 8 at 0x60040000e000 thread T0 #0 0x400eb4 (/.autofs/ilab/ilab_users/xy139/night+0x400eb4) #1 0x402911 (/.autofs/ilab/ilab_users/xy139/night+0x402911) #2 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14) #3 0x400a78 (/.autofs/ilab/ilab_users/xy139/night+0x400a78) 0x60040000e000 is located 8 bytes to the right of 8-byte region [0x60040000dff0,0x60040000dff8) allocated by thread T0 here: #0 0x7f2196e74129 (/usr/lib64/libasan.so.0.0.0+0x16129) #1 0x402071 (/.autofs/ilab/ilab_users/xy139/night+0x402071) #2 0x402899 (/.autofs/ilab/ilab_users/xy139/night+0x402899) #3 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14) Shadow bytes around the buggy address: 0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 fa =>0x0c00ffff9c00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c00ffff9c50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap righ redzone: fb Freed Heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==6841== ABORTING 方法的{p> if条件:add_student实际上永远不会按您认为的方式工作,因为当您使用不存在的密钥访问哈希时,它会返回if @roster[grade] == true,否则为值。

当密钥不存在时:

nil

而现有的键值将被返回:

@roster = {}
@roster[9] #=> nil

因此,当密钥存在时,你比较@roster = { 9 => ["AC Slater"] } @roster[9] #=> ["AC Slater"] ,这当然是一个错误的条件,因此你的代码总是执行if ["AC Slater"] == true条件。因此,对于else哈希中的成绩,您总是只有一个值。

一个小小的改变将使其发挥作用:

@roster

然而,如果你不喜欢像我这样的条件。您可以pass a blockdef add_student(student_name, grade) if @roster[grade] @roster[grade] << student_name else @roster[grade] = [] @roster[grade] << student_name end end 存储哈希密钥的默认数组@roster

initialized

现在,每当您尝试在密钥不存在时获取密钥时,将执行此块,它会为其创建一个空数组,否则返回该值。因此,您现在可以安全地将def initialize(school_name) @school_name = school_name @roster = Hash.new{ |h, k| h[k] = [] } end 方法更改为:

add_student