Метод инициализации объекта Ruby никогда не срабатывает из-за метода класса - PullRequest
0 голосов
/ 06 ноября 2011

Я работаю с пинпадом RS232 и хочу создать для него класс, который наследует от serialport gem , чтобы я мог использовать методы, которые выставляет gem serialport, например each_byte, при абстрагировании некоторых подробности при записи на ЖК-дисплей клавиатуры.

Проблема, с которой я столкнулся, состоит в том, что гем serialport определяет метод класса с именем new, который, похоже, препятствует запуску моего initialize метода.

class SerialPort
   def SerialPort::new(port, *params)
      #some code here
   end
end

require 'serialport'
class Pinpad < SerialPort
   attr_reader :test
   def initialize
      @test = "success"
   end
end

kp = Keypad.new()
puts kp.x #should be "success", will be nil

Я попытался определить свой собственный метод класса с именем new def Pinpad::new, который, по крайней мере, позволяет мне переопределить метод SerialPort::new, но все равно не вызывает код в моем методе initialize.

Я новичок в Ruby, поэтому решение, вероятно, тривиально, но я бы очень признателен за помощь.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2011

Я нашел пересылаемый модуль , который делает то, что я хочу

require 'serialport'
require 'forwardable'

Class Pinpad
   extend Forwardable
   def_delegator @sp, :each_byte, :each_byte

   def initialize
      @sp = SerialPort.new("/dev/ttyS0")
   end
end

pp = Pinpad.new() 
pp.each_byte { |byte| puts byte.chr }
0 голосов
/ 06 ноября 2011

Одним из возможных решений является переопределение self.new в вашем подклассе:

def self.new(*args)
    super
    object = self.allocate
    object.send :initialize, *args
    object
end

Идея заимствована из: Размер кода и динамические языки .Возможно, это не лучшее решение, но, с моей стороны, похоже, оно работает.Как мю слишком коротко говорит выше в своем комментарии к вашему сообщению, похоже, что это лучший повод для композиции, а не для наследования.

...