Inefficient Ruby method naming: passing namespace as argument as a way to call methods
There has got to be a more efficient way to do this in Ruby. I have a list of methods that sc开发者_如何学编程rape the same things (title, price) across multiple sites but in slightly different ways based on the code in each store. For example:
def store1_get_title
def store1_get_price
def store2_get_title
def store2_get_price
def store3_get_title
def store3_get_price
When calling all of these functions, I would just like a generic call with say a "namespace" parameter to do invoke any of these methods without having to type out all of them, something like:
for get_all_stores().each do |store|
store::get_title
store::get_price
end
...which would invoke store1_get_title, store1_get_price, store2_get_title, store2_get_price like I want. Is there something like this or a better way to do this?
Hope that makes sense. Thanks for any input!
Edit: these tasks are in rake task code.
This is a perfect use for classes. If you find two stores with the same software powering them (maybe Yahoo commerce or EBay stores) you can make instances of the classes with different parameters.
class Amazon
def get_price; end
def get_title; end
end
class Ebay
def initialize seller; end
def get_price; end
def get_title; end
end
[Amazon.new, Ebay.new("seller1"), Ebay.new("seller2")] each do |store|
store.get_price
store.get_title
end
And you can do this in any other object-oriented language by defining a base class or interface that all of the stores implement/inherit.
I don't understand the logic of your application. Perhaps you should think about a class definition (see Ken Blooms answer).
Nevertheless you could try a dynamic call with send
:
def store1_get_title
p __method__
end
def store1_get_price
p __method__
end
def store2_get_title
p __method__
end
def store2_get_price
p __method__
end
def store3_get_title
p __method__
end
def store3_get_price
p __method__
end
all_stores = ['store1', 'store2', 'store3']
all_stores.each do |store|
send("#{store}_get_title")
send("#{store}_get_price")
end
You didn't define what get_all_stores
returns. In my example I used Strings. You could add some syntactical sugar and extend String (I don't recommend this)
class String
def get_title()
send("#{self}_get_title")
end
def get_price()
send("#{self}_get_price")
end
end
all_stores.each do |store|
store.get_title
store.get_price
end
One last remark. You wrote
for get_all_stores().each do |store|
each
alone should be enough. for
is not ruby-like and in combination with each
it doen't look reasonable to me.
精彩评论