module Protocol
class Packet
class << self
attr_reader :packet_id
end
end
class A < Packet
@packet_id = 1
end
class B < Packet
@packet_id = 2
end
class NotAPacket
end
Mapping = Protocol.constants.each_with_object({}) do |constant_name, result|
klass = Protocol.const_get(constant_name)
next unless klass.is_a?(Class)
next unless klass < Protocol::Packet
result[klass.packet_id] = klass
end
end
p Protocol::Mapping
p Protocol::Mapping[1].new
bW9kdWxlIFByb3RvY29sCiAgY2xhc3MgUGFja2V0CiAgICBjbGFzcyA8PCBzZWxmCiAgICAgIGF0dHJfcmVhZGVyIDpwYWNrZXRfaWQKICAgIGVuZAogIGVuZAoKICBjbGFzcyBBIDwgUGFja2V0CiAgICBAcGFja2V0X2lkID0gMQogIGVuZAoKICBjbGFzcyBCIDwgUGFja2V0CiAgICBAcGFja2V0X2lkID0gMgogIGVuZAoKICBjbGFzcyBOb3RBUGFja2V0CiAgZW5kCgogIE1hcHBpbmcgPSBQcm90b2NvbC5jb25zdGFudHMuZWFjaF93aXRoX29iamVjdCh7fSkgZG8gfGNvbnN0YW50X25hbWUsIHJlc3VsdHwKICAgIGtsYXNzID0gUHJvdG9jb2wuY29uc3RfZ2V0KGNvbnN0YW50X25hbWUpCiAgICBuZXh0IHVubGVzcyBrbGFzcy5pc19hPyhDbGFzcykKICAgIG5leHQgdW5sZXNzIGtsYXNzIDwgUHJvdG9jb2w6OlBhY2tldAogICAgcmVzdWx0W2tsYXNzLnBhY2tldF9pZF0gPSBrbGFzcwogIGVuZAplbmQKCnAgUHJvdG9jb2w6Ok1hcHBpbmcKcCBQcm90b2NvbDo6TWFwcGluZ1sxXS5uZXc=