2019-02-16 22:24:16 +01:00
|
|
|
#
|
|
|
|
# In many respects a MetaClass is like a Class. We haven't gone to the full ruby/oo level
|
|
|
|
# yet, where the metaclass is actually a class instance, but someday.
|
|
|
|
|
|
|
|
# A Class in general can be viewed as a way to generate methods for a group of objects.
|
|
|
|
|
|
|
|
# A MetaClass serves the same function, but just for one object, the class object that
|
|
|
|
# is the meta_class of.
|
|
|
|
# This is slightnly different in the way that the type of the class must actually
|
|
|
|
# change, whereas for a class the instance type changes and only objects generated
|
|
|
|
# henceafter have a different type.
|
|
|
|
|
|
|
|
# This is still a first version, this change is not implemeted, also classes at boot don't
|
|
|
|
# have metaclasses yet, so still a bit TODO
|
|
|
|
|
|
|
|
# Another current difference is that a metaclass has no superclass. Also no name.
|
|
|
|
# There is a one to one relationship between a class instance and it's meta_class instance.
|
|
|
|
|
|
|
|
module Parfait
|
|
|
|
class MetaClass < Object
|
|
|
|
include Behaviour
|
|
|
|
|
|
|
|
attr :type, :instance_type , :instance_methods , :clazz
|
|
|
|
|
|
|
|
def self.type_length
|
|
|
|
4
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize( clazz )
|
|
|
|
super()
|
|
|
|
self.clazz = clazz
|
|
|
|
self.instance_methods = List.new
|
|
|
|
set_instance_type( clazz.get_type() )
|
|
|
|
end
|
|
|
|
|
|
|
|
def rxf_reference_name
|
|
|
|
clazz.name
|
|
|
|
end
|
|
|
|
|
|
|
|
def inspect
|
|
|
|
"MetaClass(#{clazz.name})"
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_method_for(name , type , frame , body )
|
|
|
|
method = Parfait::VoolMethod.new(name , type , frame , body )
|
|
|
|
add_method( method )
|
|
|
|
method
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_method(method)
|
|
|
|
raise "Must be untyped method #{method}" unless method.is_a? Parfait::VoolMethod
|
|
|
|
instance_methods.push(method)
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_method(name)
|
|
|
|
instance_methods.find{|m| m.name == name }
|
|
|
|
end
|
|
|
|
|
|
|
|
# adding an instance changes the instance_type to include that variable
|
|
|
|
def add_instance_variable( name , type)
|
|
|
|
self.instance_type = instance_type.add_instance_variable( name , type )
|
|
|
|
end
|
|
|
|
|
|
|
|
# setting the type generates all methods for this type
|
|
|
|
# (or will do, once we store the methods code to do that)
|
|
|
|
def set_instance_type( type )
|
|
|
|
raise "type must be type #{type}" unless type.is_a?(Type)
|
|
|
|
self.instance_type = type
|
|
|
|
end
|
|
|
|
|
2019-02-17 13:37:50 +01:00
|
|
|
# Nil name means no superclass, and so nil returned
|
2019-02-16 22:24:16 +01:00
|
|
|
def super_class
|
2019-02-17 13:37:50 +01:00
|
|
|
return nil
|
2019-02-16 22:24:16 +01:00
|
|
|
end
|
|
|
|
|
2019-02-17 13:37:50 +01:00
|
|
|
# no superclass, return nil to signal
|
|
|
|
def super_class_name
|
|
|
|
nil
|
|
|
|
end
|
2019-02-16 22:24:16 +01:00
|
|
|
|
|
|
|
end
|
|
|
|
end
|