lua-users home
lua-l archive

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


On Wed, May 30, 2012 at 10:37 PM, Tim Hill <drtimhill@gmail.com> wrote:
> The ability to attach a metatable to a userdata value is, I feel, a great
> feature of Lua as it allows C code to integrate new types into the language
> cleanly and efficiently. With a correctly setup metatable, a userdata item
> can behave as a first-class citizen in Lua code.
>
> However, it seems to me that there is one hole in this clean model: the
> inability of a metatable to project a "type" into the Lua code space.
> Specifically, regardless of metatable, the value of type(someuserdata) is
> always "userdata". This means if I have several different userdata "types"
> in Lua code I cannot use them polymorphically without tracking their type
> manually (using, say, an ephemeron table). While tostring() can be used as a
> workaround (as it is for example with file handles) this seems too much like
> a hack to me; tostring() is supposed to return a value, not a type.
>
> To my mind, the most correct way for this to work would be for the type()
> function to return the user-defined type by returning the value of
> __metatable (like getmetatable()). However, this would of course break
> existing code, so i feel we need a new function, usertype() that behave like
> type() except when there is a __metatable field in the metatable, in which
> case it returns this instead. For example:
>
> function usertype(v)
> local mt = getmetatable(v)
> if mt ~= "table" return mt else return type(v)
> end
>
> An alternative would be to create a new metatable entry, such as __type,
> that if present is used as the "type" of the userdata/table in much the same
> way __tostring() is used by the tostring() function.
>
> This allows a userdata metatable to return a string from usertype() in a way
> that extends the type() namespace. Of course this has the potential
> disadvantage that adding new types to Lua is harder, as the private
> namespace of the type() function is now opened up to add-in types, but this
> can be handled by (for example) decorating the user-defined types in
> usertype() in some manner. For example:
>
> function usertype(v)
> local ty = getmetatable(v).__type
> return ty and "_" .. ty or type(v)
> end
>
> Of course, it's not necessary to add this to the language; after all I just
> wrote the code in the above example. However, I feel that this is a generic
> feature that needs to always be available for people who are writing addon
> libraries or packages for Lua.
>
> Thoughts anyone?
> --Tim
>

The pattern I keep seeing is to provide a type() in the namespace of
your library similar to io.type() so users can dispatch on that.