Coder Social home page Coder Social logo

middleclass's People

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  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

middleclass's Issues

Feature request: Access to list of classes

I think that not having the _classes variable local allows for more extension to MiddleClass. For example, we could replicate this line here:

assert(_classes[theClass]~=nil, "Use Class:new instead of Class.new")

One way to do this might be by putting it in Object.classes or Object._classes or something like that.

Wiki update about methamethods

On wiki it's said that the full list of supported methamethods are: '__add', '__call', '__concat', '__div', '__le', '__lt', '__mod', '__mul', '__pow', '__sub', '__tostring', '__unm'
whereas I've had success with __eq as well. Is this info dated or was it not supposed to work?

Thanks

19 Oct 2009?

The date in middleclass.lua: is it meant to be 19 Oct 2009? Are you keeping it as the first release date or something?

I find it a little confusing because it says "MiddleClass - v1.4" (or something similar), and then, after your name, it gives the 19 Oct 2009 (which 1.4 obviously wasn't released).

__newindex declaration makes it impossible to have public attributes

If I declare __newindex, I can't create public attributes in initialize because __newindex is being called. Is this intentional?

class = 'middleclass.lua'

local MyClass = class('MyClass')

function MyClass:initialize(x)
    self.x = x
    --print("X = " .. self.x)                     --> error
end

local _table = {}

function MyClass:__newindex(key, value)
    _table[key] = value
    print("Key: " .. key .. "  Value: " .. value) 
end

local myInstance = MyClass:new(1)
myInstance.x = 2
print(myInstance.x)

Output:

Key: x Value: 1
Key: x Value: 2
nil

__index functions for classes

I'd love to be able to write an __index function for classes, and it would be called when the requested instance method can't be found in the subclass.

Don't understand how to work with metamethods :(

Here is my original script. It works fine without OOP:

local t = {
  pos = {2, 4},
  size = {8, 16}
}

setmetatable(t, {
  __index = function(table, key)
    if key == "x" then return table.pos[1]
      elseif key == "y" then return table.pos[2]
      elseif key == "w" then return table.size[1]
      elseif key == "h" then return table.size[2]
    end
  end,
  __newindex = function(table, key, value)
    if key == "x" then table.pos[1] = value
      elseif key == "y" then table.pos[2] = value
      elseif key == "w" then table.size[1] = value
      elseif key == "h" then table.size[2] = value
    end
  end
})

print(t.x) -- 2
t.x = 222
print(t.pos[1]) -- 222

But with middleclass it doesn't work:

local class = require "middleclass"

local T = class("T")

function T:__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]
  end
end

function T:__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
  end
end

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

local t = T:new()

print(t.x) -- nil
t.x = 222
print(t.pos[1]) -- attempt to index a nil value (field 'pos')

Mixin examples are wrong

Some of the code in the examples of mixins is wrong.

HasWings = { -- HasWings is a module, not a class. It can be "included" into classes
  fly = function ()
    print('flap flap flap I am a ' .. self.class.name)
  end
}

Where is self coming from? It should be:

function(self)

And then this:

DrinksCoffee = {
  included = function(class, coffeeTime) {
    print(class.name .. ' drinks coffee at ' .. coffeeTime)
    class.coffeeTime = coffeeTime
  }
}

Lua won't accept braces for functions. Also the function definition should include self:

function(self, class, coffeeTime)

That's all I could find. :)

Defining an instance method "name"

I just stumbled across the issue given in the title.
I knew from the documentation that for each class a static variable name is defined but I wouldn't have guessed (and find it quite restricting) that this affects the namesapce of instance methods. Don't Class.sth and instance.sth have different look-up chains?
Consider the following code sample.

local class = require 'middleclass'

local Foo = class 'Foo'
local foo = Foo()

print(Foo.name) --> Foo
assert(foo.class.name == Foo.name) -- secure fallback to get static class members
print(foo.name) --> nil

-- Foo.static.name = 'Bar' -- has no effect

function Foo:name() -- equivalent to function Foo.name(self)
	print('method "name" is called')
end

-- foo:name() -- attempt to call a nil value (method 'name')
print(Foo.name) --> function: 0x123456
print(foo.name) --> nil

Is this a bug, intended, unavoidable? What could be a workaround if one really wanted a name method? (I know that using getName would be one solution.)

aClass.subclasses never used? Why this field is always empty?

Hello! I inspected your code and its behavior in lovebird. I created a chain of classes, inherited from each other, watched in their subclasses fields and all these fields are empty! Maybe I don't get something but I think there is a bug:

self.subclasses[subclass] = true

It sholud look like this:

self.subclasses[name] = subclass

Also I can be wrong, but I feel that for loop in _propagateInstanceMethod at lines 53-58 does nothing useful.

for subclass in pairs(aClass.subclasses) do
if rawget(subclass.__declaredMethods, name) == nil then
_propagateInstanceMethod(subclass, name, f)
end
end

How to use __call

local class = require "lua-resque.deps.middleclass"
local redis = require 'redis'

local Resque_Redis = class('Resque_Redis')
function Resque_Redis:initialize(sredisServer, sredisDatabase)
  local client = redis.connect('127.0.0.1', 6379)
  self.client = client
  return client
end
function Resque_Redis.__call(m)
  self.client[m]("q")
end


return Resque_Redis

Trying to use it:

local r = Resque_Redis:new()
r:sadd('queues', queue)
attempt to call method 'sadd' (a nil value)

Error on nil superclasses

I recently ran into this problem, caused by a messy series of require() calls on my part:

local class = require("middleclass")
local Foo = class("Foo", Bar)

The problem was that the game had not yet created the Bar class due to my mismanagement of the require() order. Middleclass silently went on with this, making Object the parent of Foo instead. This caused some bugs that, admittedly, were not difficult to track down. But it got me thinking.

I would like to propose a patch where Middleclass will report such code as above is an error. In particular:

local class = require("middleclass")

-- No errors.
local Foo = class("Foo")

-- Also no errors
local Bar = class("Bar", Foo)

-- But this fails with an error because we explicitly provide
-- a parent class which does not exist.
local Baz = class("Baz", NilParentClass)

I would be happy to code a patch and test cases for this if you are interested in having such behavior in the library.

Question regarding method inheritance and overide when there are parameters

Hi there,
In the documentation, in the quick example we can read:

function Person:speak()

and then

function AgedPerson:speak()
  Person.speak(self) -- prints "Hi, I am xx."

How does one go to do the same but with a method that has parameters?

(Aka, if the first function Person:speak() had a parameter itself) like

function Person:speak(salutation)

I tried

function AgedPerson:speak(salutaion)
  Person.speak(self, salutation) 

But I didn't get it right.

Is this possible?
Thanks

properties, sorry to ask lol

Hi

i like middleclass but (even as per your advice) i was in the process of shifting over to raw metatables

as far as i can see though, middleclass shouldn't be any slower? is there some performance consideration you made to not include a strategy for properties or was it simply not featured/for cleanliness and purity of code reasons?

i am trying to figure it out, and i am thinking a little bit of the specifics of calling

object.x = 55

this means no self reference is passed unless we had to load all the functions with the references already?

Thanks for your help (and especially inspect ;) )

Wiki doesn't say that you can create instances with __call

Using this library for the first time and so far I've found it absolutely wonderful. Great job ๐Ÿ‘

I was pleasantly surprised when I've found out that this works:

local SomeClass = class("SomeClass")
local someObj = SomeClass()

I think that this must be documented, because I've found no mentions that you can do this stuff.
Any reason why SomeClass:new() is used everywhere other than missing mentions of this? Does SomeClass() have any drawbacks?

class.name doesn't work

I'm not sure if I'm doing something rong or if this actually is a problem.

When I create a class just like you do in the example (class:initialize()) then I only can access the name and super properties if I'm calling myClass.class.name or myClass.class.super. It doesn't work with myClass.name like in the example.

My code is something like this:
`
-- base class

local control = gui.class("base") -- gui.class is just middleclass

function control:initialize(parent)
self.parent = parent
-- self.name is nil here
end

return control

-- label class

local control = gui.class("label", gui.controls.base)

function control:initialize(parent, text)
gui.controls.base.initialize(self,parent)
self.text = text
-- self.name is also nil here
end

return control

-- main file
local screen = gui.controls.screen()
local label = gui.controls.label(screen,"Test Text")

-- label.name and label.super are both nil
-- label.class.name and label.class.super both work
`

What is the proper means of creating a module out of a middleclass class hierarchy

I have built a class hierarchy with middleclass and it works magnificently until I try and turn it into a module. I am new to lua but not to oop. Most instructions I find for module creation seem to cause conflicts with my middleclass hierarchy. What is your recommended way of making middleclass based class hierarchies into modules so that huge code projects can be partitioned into modules and included in new code sections?

Implementing destructors

Hi, what do you think about implementing destructors in middleclass?

That can possibly be done in a way similar to how they are implemented in Klass module - by overriding __gc metamethod (using newproxy() trick for Lua 5.1 and without it for 5.2 and above).

init.lua is still present

In the changelog you say that init.lua has disappeared, yet it is still there. I assume you forgot to remove it, right?

There's a bug in line 82

setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) or super.static[k] end })

if rawget(dict,k) is a boolean value and its value is false, it went wrong.
so you should change the or expression to if/else

Make isSubclassOf and isInstanceOf accept strings

First thank you for a pretty robust class library!

I have one helpful feature suggestion for the library that I've used in my projects. The ability to check class names by string without having to require the class object as a dependency. I hope this makes sense?

If I have multiple different classes, and I want or need to use isInstanceOf to check for other classes, I would need to require the classes I'm checking, for every class module. This will unnecessarily bloat the dependencies when all it should need to do is compare against the class name.

Instance json encode error

Hi,
I want use cjson to serialize a instance of middleclass object but get a error.

Cannot serialise table: table key must be a number or string

Here is the demo code:

local Foo = class("Foo")
local foo = Foo:new()
local cjson = require "cjson"
cjson.encode(foo)

I understand all the lua object is simulated by lua table, so in theory a object should can be convert to a json encoded text.
Would you point out the reason get this error? or give any advice how to bypass this issue?
Thanks

kenshin

about aClass.static's metamethod

could it be bettle if we change
setmetatable(aClass.static, { __index = function(,k) return dict[k] or superStatic[k] end })
to
setmetatable(aClass.static, { __index = function(
,k) return rawget(dict,k) or superStatic[k] end })
?

Hot reloading of instances and local up values

Hi!

It seems this library is unable to make use of new local values and class instance functions during a "recompile". The metatable for the instance is pointing to an already set entry and will not be updated with a fresh compile of a module with "require" or "dofile".

Does anyone have a way to add this support? I'm unable to get this working myself unfortunately

Indexable mixin for middleclass 3.x feature request

I'm porting PHP web framework to Lua. All is going well except I need something to replace PHP getter __get(). In previous versions there was Indexable mixin with index() function, I need same for middleclass 3.x.

Also question about porting, I'm replacing get_class($this) with self.class.name, is it proper to get class name in such way? Also question how to call method in parent class, the way present in wiki a bit wierd, if I try self.class.super.method(self, ...) it gives wrong parent on second level of inheritence, it gives parent of first level. My temporary solution:

local Database_Query_Builder_Select = Database_Query_Builder_Where:subclass('Database_Query_Builder_Select')
local parent = Database_Query_Builder_Where

function Database_Query_Builder_Select:initialize(columns)
    ...

    -- Start the query with no actual SQL statement
    parent.initialize(self, Database.SELECT)
end

Make it possible to include superclasses and mixins by string names

After using middleclass for some time I found myself out doing things like this:

local _M = require('middleclass')('State.Moving', require('State.Base'))
  :include(require('Mixin.Character'))
  :include(require('Mixin.Moving'))

It would be more convenient to be able to do it without constantly calling require, e.g.:

local _M = require('middleclass')('State.Moving', 'State.Base')
  :include('Mixin.Character')
  :include('Mixin.Moving')

It's something that e.g. Moose OO framework in Perl does with its extends and with keywords.

I also have read a discussion on the similar issue #52, and I think that format of an argument (i.e., string with class name vs class variable) already provides sufficient explicitness, and if in doubt / having issues, it's easy to switch back to class variables instead of strings in some particular project.

Documentation?

Wiki homepage says that "The code is reasonably commented", but middleclass.lua doesn't have a single comment. Am I missing something?

Missing documentation for isInstanceOf, isSubclassOf, allocate and subclassed

This is a very nice library - thank you for your work!

I noticed that in the library there are four default methods that aren't mentioned in the wiki documentation, namely isInstanceOf, isSubclassOf, allocate and subclassed. Was there documentation for these that got deleted from the wiki somehow? I see references to isInstanceOf and isSubclassOf in UPDATING.md, which makes me suspect that there might have been something there before. In any case, it would be nice to have some documentation and examples for these methods.

How to split a big class to several files?

How to split Game class to several files?

  • game.lua
  • game_main_menu.lua
  • game_options_menu.lua
local class = require("middleclass")
local Game = class("Game")

function Game:main_menu()
end

function Game:options_menu()
end

return Game

Static inheritance seems broken

Given the file static.lua:

local class = require("middleclass")

local C = class("C")

function C.static:foo()
  return "<static> C.static:foo"
end

function C:initialize()
  self.value = self.class:foo()
end

function C:foo()
  return "<instance> C:foo"
end

local c = C()

print(("[%s] C.static.foo"):format(C.static.foo))
print(("[%s] C.foo"):format(C.foo))
print(("[%s] c.foo"):format(c.foo))
print(("C:foo() = %q"):format(C:foo()))
print(("c:foo() = %q"):format(c:foo()))
print(("c.value = %q"):format(c.value))

local D = class("D", C)

local d = D()

print("---")
print(("[%s] D.static.foo"):format(D.static.foo))
print(("[%s] D.foo"):format(D.foo))
print(("[%s] d.foo"):format(d.foo))
print(("D:foo() = %q"):format(D:foo()))
print(("d:foo() = %q"):format(d:foo()))
print(("d.value = %q"):format(d.value))

And its output:

> lua static.lua 
[function: 0x40cf4998] C.static.foo
[function: 0x40cf4998] C.foo
[function: 0x40cfcf90] c.foo
C:foo() = "<static> C.static:foo"
c:foo() = "<instance> C:foo"
c.value = "<static> C.static:foo"
---
[function: 0x40cfcf90] D.static.foo
[function: 0x40cfcf90] D.foo
[function: 0x40cfcf90] d.foo
D:foo() = "<instance> C:foo"
d:foo() = "<instance> C:foo"
d.value = "<instance> C:foo"

You can see D's static functions addresses all point to C's instance functions and initialization of D's instances calls them, resulting in a wrong d.value (it should be the same as c.value: "<static> C.static:foo").

Memory Leak in middleclass.lua

Reference: http://love2d.org/forums/viewtopic.php?f=4&t=2278

Hi

Newbie here, I have been experimenting a bit with Lua and the Middleclass library, an apparent memory leak with Middleclass has got me totally stumped. Is this really a leak or am I misunderstanding something.

I cut my code down to just the following lines

Code: Select all
require "middleclass"

local oPlayer = class("A Player")      -- This single line is enough to show a leak

collectgarbage("collect")
local endMem = string.format("\nMemory used after Garbage Collect = %.1f kbytes", collectgarbage("count"))
print (endMem)

If I run this code repeatedly from a Lua console with dofile("myTest.lua") I get the following increasing memory usage.
Memory used after Garbage Collect = 43.8 kbytes
Memory used after Garbage Collect = 46.0 kbytes
Memory used after Garbage Collect = 48.2 kbytes
Memory used after Garbage Collect = 50.6 kbytes

If I add the line oPlayer = nil, that makes no difference either.

Sample not working

Sorry if I am getting something wrong, I am new to lua.

I was just trying to use your library and after started to play with the examples of the wiki.
I put the following in a file.

package.path = package.path .. ";../external/middleclass/?.lua"
class = require "middleclass"


Person = class('Person') --this is the same as class('Person', Object) or Object:subclass('Person')
function Person:initialize(name)
  self.name = name
end
function Person:speak()
  print('Hi, I am ' .. self.name ..'.')
end

but the result is ...


test = Person:new("test")
> test.speak()
/home/karl/tproject/abstract/teobject.lua:10: attempt to index a nil value (local 'self')
stack traceback:
	/home/karl/tprojectabstract/teobject.lua:10: in function </home/karl/tproject/abstract/teobject.lua:9>
	(...tail calls...)
	[C]: in ?

I am using lua 5.3. What do I have to do to get things working?

`includes` method to check if a class includes a mixin

It would be quite helpful to add a mixins field to classes, adding mixins to this array when include is called, and an includes method on class instances that return true if the class of that object includes the specified mixin.

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.