You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby课程类初始化方法如何限定星期参数days的合法取值?

Enforcing Valid Day Symbols in Your Ruby Course Class

Great question! Let's break this down step by step to make your Course class robust and enforce valid day values properly.

Step 1: Define Valid Days as a Class Constant

The best place to store your list of valid day symbols is as a class constant inside the Course class. This keeps the valid values centralized, easy to update, and accessible to all instances of the class. Add this right after opening the class:

VALID_DAYS = [:mon, :tue, :wed, :thu, :fri, :sat, :sun].freeze

Using .freeze prevents accidental modification of the list later—this is a good practice for constants that shouldn’t change.

If you also need to enforce valid values for time_block, you can add a similar constant (customize the values to match your use case):

VALID_TIME_BLOCKS = [:early_morning, :morning, :afternoon, :evening].freeze

Step 2: Validate the days Parameter in initialize

Next, add validation logic to your constructor to ensure any provided days are valid. We’ll handle two cases:

  • If days is nil (the default), skip validation since it’s allowed
  • If days is an array, verify every element is in VALID_DAYS

Here’s how to update your initialize method:

def initialize(course_name, department, credits, time_block = nil, days = nil)
  # Validate days
  if days
    invalid_days = days - VALID_DAYS
    unless invalid_days.empty?
      raise ArgumentError, "Invalid day(s): #{invalid_days.join(', ')}. Valid days are: #{VALID_DAYS.join(', ')}"
    end
  end

  # Validate time_block (optional—remove if you don't need this)
  if time_block && !VALID_TIME_BLOCKS.include?(time_block)
    raise ArgumentError, "Invalid time block: #{time_block}. Valid blocks are: #{VALID_TIME_BLOCKS.join(', ')}"
  end

  @course_name = course_name
  @department = department
  @credits = credits
  @students = []
  @days = days
  @time_block = time_block
end

Step 3: Fix Edge Cases in conflicts_with?

Your current conflicts_with? method will throw an error if either course has nil for days (since you can’t call any? on nil). Let’s update it to handle nil gracefully:

def conflicts_with?(course2)
  return false if self.time_block != course2.time_block
  return false unless self.days && course2.days # No conflict if either course has no days set

  self.days.any? do |day|
    course2.days.include?(day)
  end
end

Full Updated Course Class

Putting it all together (plus a cleanup of redundant methods), here’s your revised class:

class Course
  VALID_DAYS = [:mon, :tue, :wed, :thu, :fri, :sat, :sun].freeze
  VALID_TIME_BLOCKS = [:early_morning, :morning, :afternoon, :evening].freeze # Customize as needed

  attr_reader :department, :name, :credits, :time_block, :days, :students

  def initialize(course_name, department, credits, time_block = nil, days = nil)
    # Validate days parameter
    if days
      invalid_days = days - VALID_DAYS
      unless invalid_days.empty?
        raise ArgumentError, "Invalid day(s): #{invalid_days.join(', ')}. Valid days are: #{VALID_DAYS.join(', ')}"
      end
    end

    # Validate time_block parameter (optional)
    if time_block && !VALID_TIME_BLOCKS.include?(time_block)
      raise ArgumentError, "Invalid time block: #{time_block}. Valid blocks are: #{VALID_TIME_BLOCKS.join(', ')}"
    end

    @course_name = course_name
    @department = department
    @credits = credits
    @students = []
    @days = days
    @time_block = time_block
  end

  # Note: Your attr_reader already covers these, so we can remove the redundant methods!
  # def name
  #   @course_name
  # end
  # def department
  #   @department
  # end
  # def credits
  #   @credits
  # end

  def add_student(student)
    return if @students.include?(student)
    student.enroll(self)
  end

  def conflicts_with?(course2)
    return false if self.time_block != course2.time_block
    return false unless self.days && course2.days

    self.days.any? do |day|
      course2.days.include?(day)
    end
  end
end

Quick Tips:

  • I removed your redundant name, department, and credits methods since your attr_reader already handles these attributes—no need to redefine them!
  • Raising an ArgumentError is the standard Ruby way to signal invalid input to a constructor, making it clear when someone uses invalid values.
  • Using class constants makes updating valid values later a breeze (e.g., if you need to change :weds to :wed, you only edit one place).

内容的提问来源于stack exchange,提问作者Monique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:30:27