Skip to content

Object and class inspection functions

Benct Philip Jonsson edited this page May 8, 2021 · 1 revision

These are some functions for class/object inspection:

Function Purpose
is_object Check if a value is a class or object.
is_class Check if a value is a class.
is_instance Check if a value is a (sub)class or an instance of a (sub)class

is_object(value [, name, ...])

Returns:

  • false if value is not an object or class, i.e. is not a table or does not have a field __class which is a table.
  • else with one argument: the name of (the class of) value, i.e value.__class.__name.
  • else with 2+ arguments: the name of (the class of) value if it equals one of the extra arguments, or else nil.
is_object = (...) =>
  if 'table' == type @
    if 'table' == type @@ -- if it has/is a __class
      if name = @@.__name -- if the class has a name
        -- Get the extra arguments
        names = {...}
        -- Return the name if there are no extra arguments
        return name if 0 == #names
        -- Loop through the extra arguments
        for n in *names
          -- Return the name if it equals one of the extra arguments
          return name if n == name
        -- If the name does not equal any of the extra arguments
        return nil
  -- If it isn't an object or a class (with a name)
  return false

is_class(value)

Returns:

  • if value is a class object: the class name.
  • else if value is an object: false.
  • else: nil.
is_class = (...) =>
  -- If it is an object or a class (with a name)
  if name = is_object @, ...
    -- Return the name if the object is a class
    -- (if the class of the object is the object itself)
    return name if @ == @@
    -- If it is an object but not a class
    return false
  -- If it is neither a class nor an object
  return nil

is_instance(class|object, value)

Check if (the class of) arg #2 is a subclass of (the class of) arg #1 or that class itself, or (an instance of) one of its subclasses.

Returns:

  • nil if arg #1 is not a class/object per is_object.
  • nil if arg #2 is not a class/object per is_object.
  • else if (the class of) arg #2 is (the class of) arg #1 or a subclass of (the class of) arg #1: the name of (the class of) arg #2.
  • else: false.
is_instance = (obj) =>
  -- If obj is an object or a class
  if obj_name = is_object obj
    -- If arg #1 is an object or a class
    if name = is_object @
      -- Get the class of obj
      cls = obj.__class
      -- Loop through the class and its parents
      -- While cls.__parent returns a true value
      while 'table' == type cls
        -- Return  name of (the class of) obj if the (super)class of (the class of)
        -- obj is (the class of) arg #1
        return obj_name if name == cls.__name
        -- Else proceed to the parent of the (super)class of obj
        cls = cls.__parent
      -- If (the class of) arg #1 is not a superclass of (the class of) obj
      return false
  -- If any of the args isn't an object or a class.
  return nil

This function is suitable to use as a method so that you can call the method on a class or object to check if a value is a(n instance of) (a subclass of) it(s class).

Example:

class Foo
  :is_instance

class Bar extends Foo

class Baz extends Bar

Bar\is_instance Foo
-->	false
Bar\is_instance Foo!
-->	false
Bar\is_instance Bar
-->	Bar
Bar\is_instance Bar!
-->	Bar
Bar\is_instance Baz
-->	Baz
Bar\is_instance Baz!
-->	Baz
Bar\is_instance 'Bar'
-->	nil