开发者

Inefficient Ruby method naming: passing namespace as argument as a way to call methods

开发者 https://www.devze.com 2023-04-13 04:07 出处:网络
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 b

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号