lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 01/05/2014 01:40, Andrew Starks wrote:
On Wed, Apr 30, 2014 at 4:28 PM, Philipp Janda <siffiejoe@gmx.net> wrote:
You can take some inspiration from here[1].

Philipp

   [1]: http://lua-users.org/lists/lua-l/2014-04/msg00860.html
I would call this hack: Heroic.

It highlights that "Lua can't do this" or at the very least "really
doesn't want you to do this" (if Lua actually had an opinion).

I've been thinking about this topic. I abuse the string table and it
is the only non-sandboxed alteration to my libraries. My desire to do
it overcame my ability to behave and I'd prefer that they legalize
basic type metatable manipulation so I could make libraries that way,
but I can see the hazards, too. The most primary being that strings
are supposed to act like values.

So, then I was thinking about uservalues for regular types, but that
doesn't help. Then I was thinking about some kind of "_LOCALENV" table
that you could put values into and would be like env, but have the
caller's scope, but that seems tacked on and hack-ish.

I've mentioned another approach: make it so you can express the type
intent of a value. That way,  you can make an object out of a table
and "stuff" would just work with it. Something like:

setmock(my_string_object, "string")

if mock(my_string_object) == "string" then
    --do stuff on the string
end

When working with Lua or other libraries, we can't pass tables as
strings because many libraries don't accept the presence of
"__tostring" as proof that the table is supposed to be a "string":

local str_obj = setmetatable({}, {
   __tostring = function (t)
       return "called"
   end,
})
print(str_obj)
--> hello
io.write(str_obj)
--> lua: iotostring.lua:10: bad argument #1 to 'write' (string
expected, got table)


And it wouldn't work, anyway. __tostring is used as an "object ID"
method in some of my code and I suspect other's too.

As a consequence of running up against this, I've wrapped type to
support this kind of thing and it works really well. If/when I
refactor it, I'll probably choose to rename the library "mock" or
something like it, just to avoid monkey patching, as previously
discussed.

I can say that this approach works really well. I can put multiple
"mock" names on objects that can behave as multiple "types". For
example a {samples, scale} tuple is a "frequency" and a "number" so
that: (using the new name)

mock(my_profile) == "frequency"
--> true

mock(my_profile) == "number"
--> true --currently this is false, but if I use "mock", having this
true would be more useful.

--currently:
type.get(my_profile) >= "number"
--> true --my_profile contains number, but it isn't the primary "type".

Since Lua doesn't have this as part of the core library, I have to
patch things to work this way. It does nothing to help interact with
unknown libraries.

This is only a sandbox problem for strings (and functions, especially
things that expect functions but don't like functables), but this
facility avoids *most* of the motivation for patching strings in the
first place...

str "I have to wrap it in an object, %s" % { "so I'll just go on
breaking the law... for now"}

-Andrew

If ALL functions had the _ENV upvalue even when they don't need it this would be a lot easier...