Ruby捕获名称错误
我有以下两个类的代码Ruby捕获名称错误,ruby,Ruby,我有以下两个类的代码 class DeliveryService attr_reader :cities def initialize *cities @cities = cities end end class Product attr_accessor :name def initialize name @name = name end def deliver_to delivery_service, city if delive
class DeliveryService
attr_reader :cities
def initialize *cities
@cities = cities
end
end
class Product
attr_accessor :name
def initialize name
@name = name
end
def deliver_to delivery_service, city
if delivery_service.cities.include?(city)
puts "Product has been delivered"
else
puts "Сontact another delivery service"
end
end
end
我想delivery\u to
方法在提供的delivery\u服务无效(不存在)时抛出类似于“选择有效的delivery服务”的东西,但我得到的却是NameError
我试着把它放在我代码的不同地方
rescue NameError
puts "Choose valid delivery service"
但它不起作用
irb(main):001:0> require './DeliveryService.rb'
=> true
irb(main):002:0> fedex = DeliveryService.new "Moscow", "Saint-Petersburg"
=> #<DeliveryService:0x007f66ded31520 @cities=["Moscow", "Saint-Petersburg"]>
irb(main):003:0> product = Product.new "mug"
=> #<Product:0x007f66ded1e498 @name="mug">
irb(main):004:0> product.deliver_to fedex, "Moscow"
Product has been delivered
=> nil
irb(main):005:0> product.deliver_to dhl, "Moscow"
NameError: undefined local variable or method `dhl' for main:Object
from (irb):6
from /home/budkin/.rbenv/versions/2.1.2/bin/irb:11:in `<main>'
irb(main):006:0>
irb(main):001:0>require./DeliveryService.rb'
=>正确
irb(main):002:0>fedex=DeliveryService.new“莫斯科”、“圣彼得堡”
=> #
irb(主):003:0>产品=产品。新“杯子”
=> #
irb(主要):004:0>产品交付至联邦快递,“莫斯科”
产品已交付
=>零
irb(主要):005:0>产品交付至dhl,“莫斯科”
NameError:未定义的局部变量或main:对象的“dhl”方法
来自(irb):6
from/home/budkin/.rbenv/versions/2.1.2/bin/irb:11:in`'
irb(主要):006:0>
dh1
不存在,因此您需要包装尝试取消引用的部分代码
begin
product.deliver_to dhl, "Moscow"
rescue NameError => e
puts e.message
end
虽然这是一个相当混乱的方法。更好的方法是创建一个包含所有公司的数组
或集
,然后检查该集中是否定义了公司
/数组
对正确的对象使用依赖项注入
这是一个设计问题,因为您不会从类中得到NameError;当你在课堂外呼叫product.deliver_到dhl“Moscow”
时,会引发此问题。即使类定义中有一个rescue子句,调用方也会引发NameError
解决此问题的正确方法是将有效的产品对象传递给有效的DeliveryService对象。一个产品无论如何都不应该知道任何关于交付的信息;这违反了单一责任原则。因此:
class DeliveryService
def deliver product
end
end
这将为您提供一个获取产品并通过当前交付服务交付的实例方法。例如:
product = Product.new :widget
dhl = DeliveryService.new 'Moscow'
dhl.deliver product
即使执行此反转,如果传递无效对象,也会出现问题,所以不要这样做。:) 我需要为任何不存在的公司发布一条消息