Ruby中处理未创建对象:单例Email类的异常处理优化
解决方案:处理单例Email类的无效实例调用问题
当然可以用begin/raise/rescue实现需求,同时也有更优雅的防御式编程方案,下面分别给出具体实现:
一、使用异常处理(begin/raise/rescue)
核心思路是:在创建实例时,若邮箱无效就主动抛出异常,而非返回nil;调用时通过rescue捕获异常并输出指定提示。
代码实现:
# 自定义异常类 class InvalidEmailError < StandardError; end class Email include Singleton attr_reader :email def initialize(email) @email = email end def self.create(email) if valid_email?(email) instance.instance_variable_set(:@email, email) instance else raise InvalidEmailError, "Error: No email is created." end end private def self.valid_email?(email) # 替换为你的实际邮箱验证逻辑,示例用简单正则 email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) end end # 调用示例 begin email_instance = Email.create("invalid-email") puts email_instance.email rescue InvalidEmailError => e puts e.message end
当邮箱无效时,create方法会抛出InvalidEmailError,rescue块捕获后直接输出指定提示,彻底避免nil调用email方法的错误。
二、其他更安全的解决方案
1. 增加存在性判断方法
在单例类里添加email_valid?方法,调用前先判断实例有效性,避免直接调用报错:
class Email include Singleton attr_reader :email def self.create(email) if valid_email?(email) instance.instance_variable_set(:@email, email) instance else nil end end def email_valid? !@email.nil? && self.class.valid_email?(@email) end private def self.valid_email?(email) email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) end end # 调用示例 email_instance = Email.create("invalid-email") if email_instance&.email_valid? puts email_instance.email else puts "Error: No email is created." end
2. 使用Null Object模式
创建一个空的Email对象,当邮箱无效时返回该对象,调用email方法直接返回错误提示,完全规避nil的出现:
class NullEmail def email "Error: No email is created." end end class Email include Singleton attr_reader :email def initialize(email) @email = email end def self.create(email) if valid_email?(email) instance.instance_variable_set(:@email, email) instance else NullEmail.new end end private def self.valid_email?(email) email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) end end # 调用示例 email_instance = Email.create("invalid-email") puts email_instance.email # 直接输出指定错误信息
这种方式无需额外判断或异常捕获,调用方代码更简洁直观。
内容的提问来源于stack exchange,提问作者S_coderX451
相关产品推荐
相关产品推荐

