Неэффективное именование методов Ruby: передача пространства имен в качестве аргумента для вызова методов

Должен быть более эффективный способ сделать это в Ruby. У меня есть список методов, которые очищают одни и те же вещи (название, цена) на нескольких сайтах, но немного по-разному, в зависимости от кода в каждом магазине. Например:

def store1_get_title
def store1_get_price

def store2_get_title
def store2_get_price

def store3_get_title
def store3_get_price

При вызове всех этих функций я просто хотел бы, чтобы общий вызов, скажем, с параметром «пространство имен», вызывал любой из этих методов без необходимости вводить их все, например:

for get_all_stores().each do |store|
     store::get_title
     store::get_price
end

... который будет вызывать store1_get_title, store1_get_price, store2_get_title, store2_get_price, как я хочу. Есть ли что-то подобное или лучший способ сделать это?

Надеюсь, это имеет смысл. Спасибо за любой вклад!

Изменить: эти задачи находятся в коде задачи rake.


person heebee313    schedule 16.10.2011    source источник


Ответы (2)


Это идеальное использование для занятий. Если вы найдете два магазина с одинаковым программным обеспечением (например, магазины Yahoo commerce или EBay), вы можете создать экземпляры классов с разными параметрами.

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

И вы можете сделать это на любом другом объектно-ориентированном языке, определив базовый класс или интерфейс, который реализуют/наследуют все хранилища.

person Ken Bloom    schedule 16.10.2011

Я не понимаю логики вашего приложения. Возможно, вам следует подумать об определении класса (см. ответ Кена Блумса).

Тем не менее, вы можете попробовать динамический вызов с 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

Вы не определили, что возвращает get_all_stores. В моем примере я использовал строки. Вы можете добавить немного синтаксического сахара и расширить String (я не рекомендую это)

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

Последнее замечание. Вы написали

for get_all_stores().each do |store|

each одного должно быть достаточно. for не похож на рубин и в сочетании с each мне не кажется разумным.

person knut    schedule 16.10.2011