Comments 13
> а где просто одну точку
Везде можно писать двоеточие, так как двоеточие это «сахар»: Объект.функция(Объект, параметры) == Объект: функция(параметры). (upd: тут парсер всунул лишний пробел)
Ваша реализация классов немного запутана: статик, паблик, приват и всё отдельными таблицами. У вас же есть основная таблица — вот вам и статик, вот вам и паблик. Хорошая идея, как мне кажется, хранить скрытые свойства в метаданных. Их никто не увидит и доступа к ним никто не получит, если сам «силой» не влезет через getmetatable(), но так же можно читать и userdata. Получается в духе Lua.
Наследования можно осуществлять двумя путями:
1. через какую-нибудь функцию extends('MyClass', родитель);
2. через обращение к окружению: [local] MyClass = my_class_system(родитель);
Второй метод интересен и хитёр, но нужно копаться с getfenv() и debug.getlocal(). И далеко не факт, что имена переменных не потеряются.
Везде можно писать двоеточие, так как двоеточие это «сахар»: Объект.функция(Объект, параметры) == Объект: функция(параметры). (upd: тут парсер всунул лишний пробел)
Ваша реализация классов немного запутана: статик, паблик, приват и всё отдельными таблицами. У вас же есть основная таблица — вот вам и статик, вот вам и паблик. Хорошая идея, как мне кажется, хранить скрытые свойства в метаданных. Их никто не увидит и доступа к ним никто не получит, если сам «силой» не влезет через getmetatable(), но так же можно читать и userdata. Получается в духе Lua.
Наследования можно осуществлять двумя путями:
1. через какую-нибудь функцию extends('MyClass', родитель);
2. через обращение к окружению: [local] MyClass = my_class_system(родитель);
Второй метод интересен и хитёр, но нужно копаться с getfenv() и debug.getlocal(). И далеко не факт, что имена переменных не потеряются.
+4
Тут в чём особенность. Дело всё в том, что у каждой таблицы (статик паблик, статик приват, просто паблик, просто приват) выставляется разная видимость. Потому и четыре разных таблицы — каждой аккуратно присваиваются свои права доступа. Если же доступ к основной таблице открывать, то тогда можно и до приватных добраться, чего я хотел избежать абсолютно.
Двоеточие в принципе почему-то не понравилось, так то я прекрасно знаю, что можно всё через двоеточие писать (типичный сахар), но можно сказать, что челлендж был как раз от них избавиться) Мол, можно ли добиться того же без оного сахара?
К getmetatable можно и закрыть доступ (__metatable = false). Думал как раз метатейблы использовать для наследования, но что-то не додумался как, не получилось. Да и дефакто метатейбл получается такой же скрытой Upvalue таблицей, её можно и не только при помощи метатейбла сделать. Впрочем, тут в принципе подход с upvalues достаточно жёстко ограничивает свободу действий.
Насчёт getfenv() и debug.getlocal() — первый в lua 5.2 вообще вырезан, а вот debug бывает и отключён (debug = nil, особенно в каких нить embedded вариантах луа).
Вообще, хотелось бы увидеть вашу реализацию, может и смог бы чего нибудь почерпнуть.
Двоеточие в принципе почему-то не понравилось, так то я прекрасно знаю, что можно всё через двоеточие писать (типичный сахар), но можно сказать, что челлендж был как раз от них избавиться) Мол, можно ли добиться того же без оного сахара?
К getmetatable можно и закрыть доступ (__metatable = false). Думал как раз метатейблы использовать для наследования, но что-то не додумался как, не получилось. Да и дефакто метатейбл получается такой же скрытой Upvalue таблицей, её можно и не только при помощи метатейбла сделать. Впрочем, тут в принципе подход с upvalues достаточно жёстко ограничивает свободу действий.
Насчёт getfenv() и debug.getlocal() — первый в lua 5.2 вообще вырезан, а вот debug бывает и отключён (debug = nil, особенно в каких нить embedded вариантах луа).
Вообще, хотелось бы увидеть вашу реализацию, может и смог бы чего нибудь почерпнуть.
0
Точно, в Lua 5.2 getfenv заменили на _ENV.
Я могу скинуть в личку ссылку на свой говнокод годичной давности, если интересно.
P.S. Иногда, когда debug == nil явный require('debug') выручает ситуацию. Из-за того, что вырезают luaopen_debug() из автоматического подключения стандартных модулей.
upd: прошу прощения, промахнулся.
Я могу скинуть в личку ссылку на свой говнокод годичной давности, если интересно.
P.S. Иногда, когда debug == nil явный require('debug') выручает ситуацию. Из-за того, что вырезают luaopen_debug() из автоматического подключения стандартных модулей.
upd: прошу прощения, промахнулся.
0
Зачем нужен весь этот колхоз не очень понятно:
1. Есть готовые реализации, например, вот хорошая github.com/kikito/middleclass/
2. Lua предполагает несколько другую парадигму вместо ООП, вот ей и надо пользоваться.
А так получилась статья из серии «а смотрите как я могу». Можете, молодец. Но зачем это здесь? Кому нужен этот непонятный код?
> Сумбурно звучит, знаю, но лучше не могу объяснить — не спец :)
> Не судите строго, может кому-то зачем-то пригодится это решение!
Ноу коммент. Филиал ЖЖ открыт?
1. Есть готовые реализации, например, вот хорошая github.com/kikito/middleclass/
2. Lua предполагает несколько другую парадигму вместо ООП, вот ей и надо пользоваться.
А так получилась статья из серии «а смотрите как я могу». Можете, молодец. Но зачем это здесь? Кому нужен этот непонятный код?
> Сумбурно звучит, знаю, но лучше не могу объяснить — не спец :)
> Не судите строго, может кому-то зачем-то пригодится это решение!
Ноу коммент. Филиал ЖЖ открыт?
+1
Хочу лишь поблагодарить за ссылку и отметить правильность Вашего подхода (на тему парадигмы lua). Со всем остальным предпочту не согласиться.
Целью моей попытки было проверить, возможно ли это, или нет, и насколько возможно. И я считаю, что своей статьёй кому-то помог, возможно даже навёл на мысль — мне большего и не нужно.
PS: лично я считаю, что уж лучше такая статья, чем бесконечный поток малополезных новостей. Ну и смотрите хабы и теги.
Целью моей попытки было проверить, возможно ли это, или нет, и насколько возможно. И я считаю, что своей статьёй кому-то помог, возможно даже навёл на мысль — мне большего и не нужно.
PS: лично я считаю, что уж лучше такая статья, чем бесконечный поток малополезных новостей. Ну и смотрите хабы и теги.
0
> И я считаю, что своей статьёй кому-то помог
Как можно помочь плохой статьёй? Как можно помочь кодом, для понимания которого даже хорошему программисту надо затратить заметное время для понимания? Вы выложили код, почти без объяснения и думаете что это кому-то поможет? Тот кто может в нем сейчас разобраться — может наколхозить такого over 9000.
И я даже не говорю ещё про то, что так в lua лучше не делать и про вред велосипедостроения.
> что уж лучше такая статья, чем бесконечный поток малополезных новостей
Это плохая позиция. «Остальные выкладывают трешак, ну и я выложу тоже почему нет».
Как можно помочь плохой статьёй? Как можно помочь кодом, для понимания которого даже хорошему программисту надо затратить заметное время для понимания? Вы выложили код, почти без объяснения и думаете что это кому-то поможет? Тот кто может в нем сейчас разобраться — может наколхозить такого over 9000.
И я даже не говорю ещё про то, что так в lua лучше не делать и про вред велосипедостроения.
> что уж лучше такая статья, чем бесконечный поток малополезных новостей
Это плохая позиция. «Остальные выкладывают трешак, ну и я выложу тоже почему нет».
+1
Я готов в меру своих возможностей ответить на вопросы по выложенному коду при необходимости. Пока вопросов нет — наверное, не всё так плохо, как Вам кажется.
Лично я считаю, что lua настолько мощный язык, что в нём реально реализовывать самые разные парадигмы, в том числе классический ООП, что и пытаюсь показать этой статьёй. Опять таки, замечу, что неспроста разместил данную статью в блок «Ненормальное программирование» — ибо согласен, что всё это велосипедостроение и нарушение «парадигмы lua». Но… Ну и что! Возможно, не мне одному придётся как-нибудь реализовывать нечто подобное, вот и возможно этот код немного поможет реализовать нечто иное, но схожее.
Дискуссия идёт в никуда, предлагаю её свернуть.
Лично я считаю, что lua настолько мощный язык, что в нём реально реализовывать самые разные парадигмы, в том числе классический ООП, что и пытаюсь показать этой статьёй. Опять таки, замечу, что неспроста разместил данную статью в блок «Ненормальное программирование» — ибо согласен, что всё это велосипедостроение и нарушение «парадигмы lua». Но… Ну и что! Возможно, не мне одному придётся как-нибудь реализовывать нечто подобное, вот и возможно этот код немного поможет реализовать нечто иное, но схожее.
Дискуссия идёт в никуда, предлагаю её свернуть.
-1
На практике все эти нагромождения искусственных классов мало нужны.
Table вполне себе объект. И очень просто реализуются в нём private и public.
Вот мой пример:
После загрузки этого модуля объекты создаются простым вызовом функций
Table вполне себе объект. И очень просто реализуются в нём private и public.
Вот мой пример:
local _M = {} -- module table
_M.someProperty = 1 -- class properties
local function createText()
-- local functions are still valid, but not seen from outside - "private"
end
local privateVar -- so do local variables
_GLOBAL_VAR -- without local it's global
function _M.staticMethod(vars)
-- this is class method like function (dot)
-- there is no "self"
end
function _M:someMethod(vars)
-- this is object method like function (colon)
-- there is "self"
end
function _M:newBaseObject()
-- Here goes constructor code
local object = {}
object.vars = 'some vars'
object.name = 'BaseObject'
object.property = self.someProperty -- from module
local privateObjectVar = 'my_secret' -- private, can't be seen from outside
function object.staticMethodInc(i) -- without colon it's "static"
return i + 1
end
function object:sign(song)
print(self.name .. ' is singing ' .. song)
end
function object:destroy()
-- optional destructor, after this to delete an object you just need to remove all references to it
self.vars = nil
end
return object
end
-- Now inheritance
function _M:newChildObject()
local object = self:newBaseObject()
-- override any methods or add new
object.name = 'ChildObject'
function object:tell(story)
print(self.name .. ' is telling ' .. story)
end
return object
end
return _M -- return this table as a module to require()
После загрузки этого модуля объекты создаются простым вызовом функций
local MyNewObject = thatModule:newChildObject()
0
Моя цель была как раз избавиться от двоеточия :) Так-то всё абсолютно верно.
Да и смущает меня local privateVar — это вы объявляете видимость в пределах файла. Если несколько классов в одном файле могут быть проблемы. Например для того же наследованного класса здесь вы не можете задать свои собственные статические переменные — они тот час же станут общими и для родительского, что считаю недопустимым. Впрочем кому как нравится.
Да и ИМХО мой результирующий шаблон создания класса выглядит проще.
На самом деле появилась идея и как с моим способом реализовать наследование, но это я уже буду экспериментировать, видимо, вне хабра.
Да и смущает меня local privateVar — это вы объявляете видимость в пределах файла. Если несколько классов в одном файле могут быть проблемы. Например для того же наследованного класса здесь вы не можете задать свои собственные статические переменные — они тот час же станут общими и для родительского, что считаю недопустимым. Впрочем кому как нравится.
Да и ИМХО мой результирующий шаблон создания класса выглядит проще.
На самом деле появилась идея и как с моим способом реализовать наследование, но это я уже буду экспериментировать, видимо, вне хабра.
0
>> Моя цель была как раз избавиться от двоеточия
Ужас. Двоеточие как раз помогает.
local privateVar — это именно private для модуля. Private для объекта это local privateObjectVar чуть ниже. Так что всё нормально с видимостью.
Проще? Ну, хорошо, вот шаблон без всего лишнего:
Проще некуда.
Ужас. Двоеточие как раз помогает.
local privateVar — это именно private для модуля. Private для объекта это local privateObjectVar чуть ниже. Так что всё нормально с видимостью.
Проще? Ну, хорошо, вот шаблон без всего лишнего:
local function newObject()
local object = {}
object.publicProperty = 'Some property'
local privateVar = 'my_secret'
function object:someMethod(value)
print(self.publicProperty, privateVar, value)
end
function object:destroy()
self.publicProperty = nil
privateVar = nil
end
return object
end
Проще некуда.
0
Спасибо, пригодилось!
0
Sign up to leave a comment.
Классы в lua, или избавляемся от двоеточия