Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- This is a changelog for this program: https://pastebin.com/t2TvSiSU
- Full documentation for this program: https://pastebin.com/upj3fgyZ
- A guide for Lua metatables: https://pastebin.com/Kf8LxzE9
- 2024/05/23:
- • Removed the local variables 'protectedObject' and 'protectedClass' and moved
- the strings to where they were being used because they were only being used
- once.
- 2023/12/01:
- • Fixed some typos in the documentation.
- 2023/09/09:
- • Updated part of the documation to explain why the 'keys' table and for loops
- are inside the '__pairs' metamethod.
- 2023/09/08:
- • Today I've learned how to use the '__pairs' metamethod, and in doing so I
- managed to solve two problems while I was trying to solve only one.
- • The pairs metamethod now has a default function that can be overwritten in the
- class definition.
- • The default function will iterate over both the public and read-only tables.
- So now using 'pairs' in a for loop will give you ALL public and read-only
- methods and properties.
- • The default metamethod is applied within the 'readOnly' function.
- • By implementing this addition, it also solved the issue of the lua prompt not
- being able to autocomplete read-only data. This was a complete accident, but
- very satisfying that I solved two problems at once.
- • The documentation and metatables guide have been updated to reflect these
- changes and what I've learned today.
- 2023/09/05:
- • It seems like the functionality of metatables has changed drastically since I
- last tested them with this script, so this update comes with a lot of changes.
- • Fortunately these changes shouldn't break anyone's scripts.
- Part 1: Diagnosing the First Problem
- • When using the interactive lua prompt in ComputerCraft, it uses
- 'textutils.complete' to autocomplete methods, and as it turns out, that
- function doesn't like it if 'getmetatable' doesn't return a table or nil.
- • As a result, the changes I made a couple days ago to the class constructor and
- read-only function cause the lua prompt to crash. The culprit is at line 1005
- of '/rom/apis/textutils.lua'.
- • Looking at the code, there's a very simple fix for the API that would avoid
- this whole problem, but unfortunately I don't have the power to push that fix
- to everyone who might use this script.
- • I also noticed with the way I had it before that read-only methods don't show
- up in the autocomplete. So I came up with a new idea.
- Part 2: The Solutions
- • The change I've decided to make was to set '__metatable' to false by default.
- This allows the textutils API to skip over that problematic line, but the
- read-only methods still won't show up in autocomplete.
- • What you could do instead is set your own '__metatable' to a "fake" metatable
- with an '__index' containing new elements whose keys match the real read-only
- '__index'. This makes it so the real metatable can't be changed while allowing
- the methods to appear in autocomplete. You can't prevent the fake metatable
- from being edited, unfortunately.
- • On that note, if you set your own '__metatable' to anything else, you should
- avoid setting it to anything other than a table, a string, or 'false'.
- • If you want 'getmetatable' to return something completely immutable other than
- the default 'false', use a string because it has metamethods so you won't run
- into these problems.
- • The class constructor has been reworked to use the 'readOnly' function for
- setting its '__metatable'.
- Part 3: Diagnosing and Fixing the Second Problem
- • On another note, '__newindex' no longer stops existing public elements from
- being changed, but it still stops new elements from being added.
- • It also now stops elements from being added or removed with 'table.insert' and
- 'table.remove', so I've updated my metatables guide and the documentation for
- this script with the new info. 'protected = true' can still be used.
- • This also means that existing public elements are now mutable, even if they're
- protected. This also doesn't stop elements from being removed by assigning
- them to nil.
- Part 4: Diagnosing and Fixing the Last Two Problems
- • Something has also apparently changed with '__len', so I've updated the
- default function to stop it from causing stack overflows.
- • Apparently looping through the indecies goes through the parent table and
- '__index' as if they were one table. So now the default '__len' only returns
- the single length value. That works out since it also apparently can return no
- more than a single value now.
- • I realized the read-only table was being applied to '__index' twice. Thanks to
- the changes I made to '__len' this is no longer needed in the object
- constructor so this is now handled solely by 'readOnly'.
- 2023/09/03:
- • Constructor method now runs before the readOnly function, so that the
- constructor can set up public members before they become protected.
- • Protected public members can't be changed after the object is created. If you
- want members that are immutable externally but not internally, use readOnly.
- • Fixed a typo in the documentation.
- • Changed 'metatable' to the correct metamethod '__metatable' in the class
- constructor.
- • Changed '__metatable' from an empty string to an empty function in the class
- constructor and in the readOnly function.
- 2023/07/08:
- • Removed the commented code at line 26.
- • Removed a little bit of excess white space.
- • Cleaned up some typos and verbage in the changelog.
- 2023/03/10:
- • Fixed 'typeCheck' not throwing error messages in the correct scope.
- • Edited some parts of the documentation to fix typos and be slightly more
- concise.
- 2023/03/09:
- • Fixed a bug in which the object was not getting returned from the object
- constructor.
- 2023/03/08:
- • This update completely fixes inheritance, which I broke several udpates ago
- with the more efficient utilization of metatables.
- • This update completely overhauls the program, and it will break any programs
- that used previous versions (again), so make sure to update all your programs
- that use this script if you haven't done so after today's date.
- • The 'Class' function has been renamed to 'Object' to make way for a new
- 'Class' function. The object constructor can still be used for its original
- purpose, however inheritiance has been removed because I've changed how
- inheritance works.
- • The new 'Class' function is the class constructor, which can be used to create
- classes from "headers" with a syntax much more similar to headers in C++.
- • Make your class definitions inside a function that returns a table using the
- correct format (same as it's always been, minus the 'inherit' table). This
- function will serve as a header that is passed to the class constructor and a
- class will automatically be created.
- • When you call the class as a function, it will pass the header into the
- object constructor, which will create an object from the class.
- • You can still create your class table manually and pass that directly to the
- object constructor.
- • If you instead call the method '.h()' from the class it will return a table
- with all of the class definitions. This can then be used to create
- inheritance. A full guide on how this works can be found here:
- https://pastebin.com/upj3fgyZ
- 2023/02/26:
- • This update is my solution for the problem mentioned in yesterday's udpate.
- It's a big one and and it comes in multiple parts for easier readability.
- Phase 1:
- • I've realized I was using __newindex wrong before I learned how metamethods
- are supposed to work. It has been reimplemented with a default state.
- • The 'protected' key has been renamed to 'readOnly'. Make sure to update all
- your programs that use this script if you haven't done so after today's date.
- • The 'protected' key is now a boolean value.
- • When 'protected' == true __newindex will be a function that throws an error if
- the user attempts to change public members.
- • If you set your own __newindex, it will be overwritten if 'protected' == true.
- Phase 2:
- • By default, __len will return the length of both the public and read only
- tables, instead of just either or.
- • The arguments for readOnly() have been rearranged. 'meta' comes before 'ro'.
- • Added an 'invert' argument to typeCheck(). If set to true, it will throw an
- error if the type of value IS equal to 'types' rather than is NOT equal.
- • Added comments with new documentation of how to use this script.
- Phase 3:
- • There are no longer any required defaults for metamethods.
- • __index will be nil by default.
- • __index will be overwritten by the readOnly member, but not by its default.
- • You can now set __metatable to whatever you want. Setting it to nil would be
- the same as not having it at all, which defaults to "" as that is the closest
- equivalent to nothing without setting it to nil.
- Phase 4:
- • To recap what hasn't changed since the last update:
- • Inheritance still only works for public members. Read only members and
- metamethods will need to be added manually.
- • By default, __call will be an empty function that does nothing.
- • __call will be overwritten by the member 'ctor', but not by its default.
- • __len will not be overwritten by its default.
- • All metamethods not mentioned here are free to use for whatever you want.
- 2023/02/25:
- • The change I made yesterday to the readOnly function broke inheritance. It is
- no longer possible for classes to inherit protected members. Inheritance will
- be restricted to public members only until I can come up with a fix or
- workaround for this.
- • Reworked how the __call metamethod is handled.
- • The object will set __call to members.ctor if members.ctor has been defined.
- • If members.ctor is not defined but __call is defined then it stays as is.
- • If __call is not defined then a default function that does nothing will be
- set.
- 2023/02/24:
- • readOnly() - Swapped __newindex for __metatable for protected members.
- • Protected members are no longer accessible through getmetatable.
- • __newindex is now available for use in the meta member, and using __metatable
- should instead be avoided.
- • __len will have a default function that can be overwritten by the object
- class.
- 2023/02/23:
- • Added argument to readOnly() to allow metamethods.
- • Added argument to Class to allow metamethods.
- • Changed first error check in Class to be handled in typeCheck().
- • Added "ctor" member for constructor methods.
- • Avoid using the __index, __newindex, and __call metamethods, as they will be
- overwritten by the object constructor.
- • Removed example code to reduce file size.
- • Reformatted the changelog so it's a bit cleaner than before.
- 2023/02/08:
- • Added some comments at the top about the pastebin link and the directory this
- file should be saved in a ComputerCraft computer.
- 2021/08/18:
- • Exposed 'typeCheck' as a global function.
- • Added a comment indicating where example code starts.
- • Updated the documentation.
- 2021/07/30:
- • Fixed a bug caused by a typo.
- 2021/07/29:
- • The code that sets protected variables as a read-only metatable has been moved
- from the object constructor to its own global function so it can be used to
- set read-only tables beyond the scope of the object constructor.
- • I've appended the end of the instructions about members to reflect this
- change: I found a valid use case for different members with the same name.
- • A read-only protected metatable can be used to reference a private table of
- the same name without allowing it to be changed externally.
- 2021/07/28: Day 1 patch:
- • Fixed a bug from a last minute change I did before I posted it on pastebin.
- • Added an instruction to the comments about protected table variables that I
- didn't think of until now.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement