Reputation: 361
I have a class that calls different suppliers to find if an item is available. How do I execute the class that each constant returns?
class ItemProvider
ADAPTER_ONE = Providers::ItemFromSupplierOne
ADAPTER_TWO = Providers::ItemFromSupplierTwo
def get_item(item)
id = ItemDetail.new(item)
%w(ADAPTER_ONE ADAPTER_TWO).each do |provider|
item_detail = provider.new(id)
break if item_detail.valid?
end
item_detail
end
Upvotes: 0
Views: 68
Reputation: 1095
Yup you have an array of strings not constants but if you want to go down that road in using classes from strings well it will be nice if you look at http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.UuGdmGQ1i2w .Maybe it is not directly related to your problem but it is a good read.
Upvotes: 1
Reputation: 237010
Your problem is that you aren't making an array that contains the constants' values; you're making an array with the strings "ADAPTER_ONE" and "ADAPTER_TWO". The %w()
syntax always makes an array of strings — it doesn't resolve variable names.
What you want is to change your get_item
code to something like this:
def get_item(item)
id = ItemDetail.new(item)
[ADAPTER_ONE, ADAPTER_TWO].each do |provider|
item_detail = provider.new(id)
break item_detail if item_detail.valid?
end or nil # break automatically makes the block return the value you break with
end
As an aside, personally, I think I'd rewrite it like this:
def get_item(item)
id = ItemDetail.new(item)
[ADAPTER_ONE, ADAPTER_TWO].map {|provider| provider.new(id) }.find &:valid?
end
Upvotes: 2