Вызов метода методом в Ruby - PullRequest
0 голосов
/ 24 августа 2018

У меня есть модуль, который генерирует номер телефона в нужном мне формате.

module PhoneNumber
  def self.prefix
    '+'
  end
  def self.country
    rand(1..9).to_s
  end
  def self.code
    rand(100..999).to_s
  end
  def self.number
    rand(1000000..9999999).to_s
  end
end

Я использую это следующим образом. Или как отформатированная строка "#{}#{}".

phone_number = PhoneNumber.prefix +
               PhoneNumber.country +
               PhoneNumber.code +
               PhoneNumber.number

Я хочу переписать тело модуля таким образом, так что я могу использовать его в точечном формате.

PhoneNumber.prefix.code.number

Ответы [ 3 ]

0 голосов
/ 24 августа 2018

Для цепочки методов нужно в основном постоянно возвращать self из всех методов, которые вы собираетесь соединить:

module PhoneNumber
  @number = ''
  def self.prefix
    @number << '+'
    self
  end
  def self.country
    @number << rand(1..9).to_s
    self
  end
  def self.code
    @number << rand(100..999).to_s
    self
  end
  def self.number
    @number << rand(1000000..9999999).to_s
    self
  end
  def self.to_s
    @number
  end
end

puts PhoneNumber.prefix.code.number
#⇒ +9065560843

Обратите внимание на явную реализацию #to_s для последнего шага, поскольку вы, вероятно, хотите получить в качестве результата строку, а не сам класс.

У этой реализации есть сбой: ее трудно использовать повторно, поскольку существует один общий @number, поэтому вам лучше сделать все методы экземплярами методов и выполнить:

class PhoneNumber
  def initialize
    @number = ''
  end
  def prefix
    @number << '+'
    self
  end
  def country
    @number << rand(1..9).to_s
    self
  end
  def code
    @number << rand(100..999).to_s
    self
  end
  def number
    @number << rand(1000000..9999999).to_s
    self
  end
  def to_s
    @number
  end
end

puts PhoneNumber.new.prefix.code.number
#⇒ +6117160297

Теперь это работает для последующих вызовов.

0 голосов
/ 24 августа 2018

Оберните вашу строковую конструкцию в метод класса

«Формат с точками» - это действительно набор связанных методов.Хотя вы могли бы предположительно сделать что-то похожее на то, что вы пытаетесь сделать, добавив вывод каждого метода класса в строку в цепочке методов, я бы посчитал это хрупким и неприятным ООП-дизайном.

На семантическом уровне каждый метод в цепочке означает «сделать х возвращаемому значению предыдущего метода».Если вы хотите описать элементы объекта или другой тип инициализации, есть более идиоматические способы сделать это.

Не внося существенных изменений в существующий код, вы можете просто добавить PhoneNumber # createКлассный метод, чтобы сделать тяжелую работу за вас.Например:

module PhoneNumber
  def self.create
    [self.prefix, self.country, self.code, self.number].join
  end

  def self.prefix
    '+'
  end

  def self.country
    rand(1..9).to_s
  end

  def self.code
    rand(100..999).to_s
  end

  def self.number
    rand(1000000..9999999).to_s
  end
end

if __FILE__ == $0
  puts PhoneNumber.create
end

Присоединение к массиву объектов String, возвращаемых вашими другими методами класса, является достаточно идиоматичным, семантически понятным и обходит необходимость изменять существующие методы класса, которые в настоящее время могут выполнять другие объекты в ваших программах.полагаться на.Это локализует изменения, что часто хорошо в дизайне ООП.

Параметризация метода или , преобразующая ваш модуль в класс , как описано в других ответах на вашвопрос, также есть разумные альтернативы.Естественно, ваш пробег и стилистические вкусы могут отличаться.

0 голосов
/ 24 августа 2018

Я согласен с Тоддом, что ты не должен этого делать;будет неудобно внедрять и вводить в заблуждение людей, которые читают код (включая вас самих в будущем), поскольку это не типичный способ написания операций, о которых вы говорите.

Тем не менее, если выесли вы действительно хотите это сделать, вам нужно предоставить метод с именем prefix, который возвращает другой объект с методом code и т. д., сохраняя состояние по цепочке и объединяя строки в конце.Ситуация станет еще сложнее, если вы захотите поменять порядок.

Настоятельно порекомендуйте метод, который выглядит следующим образом:

PhoneNumber.build(:prefix, :code, :number)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...