2010-05-29 2 views
1

Я пишу класс Ruby, который распространяется на TCPSocket. Предположим, это выглядит примерно так:Наложение на гнездо Ruby

class FooSocket < TCPSocket 
    def hello 
     puts 'hello' 
    end 
end 

У меня есть TCPServer прослушивания входящих соединений

server = TCPServer.new 1234 
socket = server.accept 

Когда мой сервер, наконец, принимает соединение, он будет возвращать TCPSocket. Тем не менее, я хочу FooSocket, чтобы я мог позвонить socket.hello.

Как я могу сменить TCPSocket на номер FooSocket?

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

Возможно, самым простым решением является написать класс, который инкапсулирует TCPSocket, и просто передать сокет, возвращенный accept в качестве параметра. Тем не менее, мне интересно знать, как это сделать через наследование - я пытался склонить голову, но не могу понять.

Заранее благодарен.

ответ

1

Я думаю, что самый простой способ сделать это - сделать FooSocket модуль, а затем extend его в свои TCPSocket s, которому нужны специальные методы. Вот некоторые примеры того, как это может быть использовано:

module FooSocket 
    def hello 
    self.puts 'hello' # could also be written without the 'self', 
    end     # but it is clearer this way because it may 
end     # be mistaken for the Kernel method. 

server = TCPServer.new 1234 
socket = server.accept.extend FooSocket 

Вы также можете легко отменить TCPServer вернуть один из них:

class TCPServer 
    alias old_accept accept 
    def accept 
    old_accept.extend FooSocket 
    end 
end 

Если вы не хотите, чтобы переопределить стандартные классы, вы можете определите одноэлементный класс на своем сервере (что я и сделаю), потому что у вас скорее всего будет только один сервер. Для этого замените строку class TCPServer в приведенном выше примере на class << server.

0

Вы должны переопределить accept в TCPServer класса возвращать FooSocket вместо TCPSocket, либо через повторное открытие класса, или подклассов и с помощью этого. Ваша идея оформить экземпляр TCPSocket после того, как он был возвращен accept, чище, я думаю.

Смежные вопросы