Coder Social home page Coder Social logo

classic's People

Contributors

rxi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

classic's Issues

is method has problems when value is nil. workaround?

There seems to be a problem with the design of the is method.
You can't do things like nil:is(SomeType)
This makes it pretty much useless for type checking as you have to guarantee that class variables are never nil.

I tried implementing it as a helper function with a little change...

function is(self, T)
  if self == T then
      return true
  else
      local mt = getmetatable(self)
      while mt do
      if mt == T then
          return true
      end
      mt = getmetatable(mt)
      end
  end
  return false
end

but it has the same problem.

Maybe there is a way to get around it?
This would also effect #20

Multiple inheritance error

Hi.

I am trying to implement multiple inheritance but when I use more than 2 in a chain, I get the following error:

Error: [love "boot.lua"]:48: Failed to initialize filesystem: already initialized

This is how my code looks like:

Car.lua

local Car = Classic:extend()

function Car:new(_wheels)
  self.wheels = _wheels
end

return Car

FamilyCar.lua

local Car = require "Car"

local FamilyCar = Car:extend()

function FamilyCar:new(_seats, _wheels)
  self.super.new(self, _wheels)
  self.seats = _seats
end

return FamilyCar

SportCar.lua

local FamilyCar = require "FamilyCar"

local SportCar = FamilyCar:extend()

function SportCar:new(_engine, _seats, _wheels)
  self.super.new(self, _seats, _wheels)
  self.engine = _engine
end

return SportCar

main.lua

Classic = require "classic"

local FamilyCar = require "FamilyCar"
local SportCar = require "SportCar"

peugeot = FamilyCar(4,4)
ferrari = SportCar("V8", 2, 4) --this is causing the error

function love.draw()
  love.graphics.print(peugeot.wheels)
end

Here is a project that reproduce the problem:
classictest.zip

I am uncertain if is it a bug, limitation or something I am doing wrong.
I would appreciate any help.

Using:
LOVE 11.4
classic.lua
macOS 12.3.1

Thank you.

Allow mixins to be separated.

Hi, I think that mixins are also useful for acting as a sub-class that can be shared between multiple classes instead of making another base class. With that level of abstraction, i think that implemented mixins should have their own container.
Here's a snippet:

local Human = classic:extend()
local Power = classic:extend()
function Power:magic() end

Human:implement(Power)

function Human:cast()
  --instead of 
  Human:magic()
  --i suggest:
  Human.Power:magic()
end

Also, Power class should have it's own self table.
To access the Human class from Power: self.parent.human_name

using :new() for creating instances silently fails

For clarification: If you have a class Point (like the example in the docs), and then want to create a new Point which is correctly done so: local p = Point(3,4)
But if you instead do: local p = Point:new(3,4) it just does nothing.
Maybe it's just me who ran into this, but the mistake was not very obvious. Raising an error as hint would be nice, or allowing it as kind of alternative syntax. Whichever is easier, I guess.

Hide meta methods

Consider hiding the meta methods.
Maybe something like this..

local Object   = {}
local Meta     =
{
	__call  = function(self, ...)
		local obj = setmetatable({}, self)
		obj:new(...)
		return obj
	end,
	
	__tostring = function(self)
	  return "Object"
	end,
	
	__index = Object
}
setmetatable(Object, Meta)

Extending the same base class in two different objects creates weird data duplication problems

This can be better explained by looking at the following example, where I create three different classes: a base class called BaseClass, that's being extended by both ClassOne and ClassTwo.

Object = require "classic"

-- BaseClass provides a say() method
local BaseClass = Object:extend()
function BaseClass:new(name)
  self._name = name
end
function BaseClass:say()
  print("Hello " .. self._name)
end

-- ClassOne extends BaseClass
local ClassOne = BaseClass:extend()
function ClassOne:new()
  ClassOne.super:new("Mark")
end

-- ClassTwo extends BaseClass
local ClassTwo = BaseClass:extend()
function ClassTwo:new()
  ClassTwo.super:new("John")
end

-- ===================================
-- =       Let's try it out:         =
-- ===================================

local class_one = ClassOne()
local class_two = ClassTwo()
class_one:say()
class_two:say()

This doesn't work, instead of printing

Hello Mark
Hello John

it prints:

Hello John
Hello John

It seems like the initialization of ClassTwo() overwrites the _name variable in ClassOne().

Why is this happening?

Properties

Can you support getter and setter properties by appending get- or set- at the beginning of a function?

Difference between middleclass, classic and oo

-- https://github.com/kikito/middleclass
local middleclass = require "middleclass"
local CreatureMC = middleclass("CreatureMC")
function CreatureMC:__call() print("CreatureMC was called!") end
local AnimalMC = CreatureMC:subclass("AnimalMC")
local CatMC = AnimalMC:subclass("CatMC")
local tomMC = CatMC()
print(tomMC) -- instance of class CatMC
print(pcall(tomMC)) -- called, no errors


-- https://github.com/rxi/classic
local classic = require "classic"
local CreatureCL = classic:extend()
function CreatureCL:__call() print("CreatureCL was called!") end
local AnimalCL = CreatureCL:extend()
local CatCL = AnimalCL:extend()
local tomCL = CatCL()
print(tomCL) -- nil !?
print(pcall(tomCL)) -- called, error (attempt to call a nil value)


-- https://github.com/limadm/lua-oo
local oo = require "oo"
local CreatureOO = oo()
function CreatureOO:__call() print("CreatureOO was called!") end
local AnimalOO = CreatureOO:extend()
local CatOO = AnimalOO:extend()
local tomOO = CatOO()
print(tomOO) -- table
print(pcall(tomOO)) -- error (attempt to call a table value)

Metamethods doesn't works! ;(

Here is the difference between classic and middleclass:

local MiddleClass = require "middleclass"
local M = MiddleClass("M")


function M:initialize()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function M:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else rawget(self, key)
  end
end


function M:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end


local m = M()

assert(m.x == 2)
m.x = 222
assert(m.pos[1] == 222)

print("No errors in MiddleClass.")


local Classic = require "classic"
local C = Classic:extend()


function C:new()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function C:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else rawget(self, key)
  end
end


function C:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end


local c = C()

assert(c.x == 2)
c.x = 222
assert(c.pos[1] == 222)

print("No errors in Classic.")

No errors in MiddleClass.
luajit: ../lib/classic.lua:58: attempt to call method 'new' (a nil value)

How to extend a method?

Hello. I want to extend existing method when extending a class (just add a new function to it, not owerwrite), but don't know how to do it. Here is an example:

local Object = require "classic"
local A = Object:extend()

function A:new()
  function self.sayHi()
    print("Hi from A!")
  end
end

local B = A:extend()

function B:new()
  B.super.new(self)
  function self.sayHi()
    -- B.super.sayHi() -- not working
    print("Hi from B!") -- overwrites
  end
end

local b = B()
b.sayHi() -- Hi from B only!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.