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
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
p mapping
p mapping[1].new
bW9kdWxlIFByb3RvY29sCiAgY2xhc3MgUGFja2V0CiAgICBjbGFzcyA8PCBzZWxmCiAgICAgIGF0dHJfcmVhZGVyIDpwYWNrZXRfaWQKICAgIGVuZAogIGVuZAoKICBjbGFzcyBBIDwgUGFja2V0CiAgICBAcGFja2V0X2lkID0gMQogIGVuZAoKICBjbGFzcyBCIDwgUGFja2V0CiAgICBAcGFja2V0X2lkID0gMgogIGVuZAoKICBjbGFzcyBOb3RBUGFja2V0CiAgZW5kCmVuZAoKbWFwcGluZyA9IFByb3RvY29sLmNvbnN0YW50cy5lYWNoX3dpdGhfb2JqZWN0KHt9KSBkbyB8Y29uc3RhbnRfbmFtZSwgcmVzdWx0fAogIGtsYXNzID0gUHJvdG9jb2wuY29uc3RfZ2V0KGNvbnN0YW50X25hbWUpCiAgbmV4dCB1bmxlc3Mga2xhc3MuaXNfYT8oQ2xhc3MpCiAgbmV4dCB1bmxlc3Mga2xhc3MgPCBQcm90b2NvbDo6UGFja2V0CiAgcmVzdWx0W2tsYXNzLnBhY2tldF9pZF0gPSBrbGFzcwplbmQKCnAgbWFwcGluZwpwIG1hcHBpbmdbMV0ubmV3Cg==