Skip to content

[Feature request] Computed properties #219

@SkyyySi

Description

@SkyyySi

Some languages allow defining methods that can be used like object attributes. For example, in JavaScript:

class Foo {
    get x() {
        console.log("Getting x");
        // In JS, member names starting wtih `#` are private and cannot
        // be accessed from the outside by any means.
        return this.#x;
    }

    set x(value) {
        console.log("Setting x to", value);
        this.#x = value;
    }
}

I would appreciate it if YueScript could do something similar. It could look something like this:

import "yue"

class Foo
    get x: () =>
        print("Getting x")
        @_x

    set x: (value) =>
        io.write("Setting x to ")
        yue.p(value)
        @_x = value

The output could then be something like this:

local yue = require("yue")
local Foo
local _class_0
local _base_0 = {}
local _index_0 = rawget(_base_0, "__index")
if _index_0 == nil then
	_index_0 = _base_0
end
if type(_index_0) == "table" then
	local _index_1 = _index_0
	_index_0 = function(_, key)
		return _index_1[key]
	end
end
local _newindex_0 = rawget(_base_0, "__newindex")
if _newindex_0 == nil then
	_newindex_0 = rawset
end
rawset(_base_0, "__index", function(self, key)
	local properties = rawget(_class_0, "__properties")
	local property = rawget(properties, key)
	if property ~= nil then
		local getter = rawget(property, "get")
		if getter ~= nil then
			return getter(self)
		end
	end
	return _index_0(self, key)
end)
rawset(_base_0, "__newindex", function(self, key, value)
	local properties = rawget(_class_0, "__properties")
	local property = rawget(properties, key)
	if property ~= nil then
		local setter = rawget(property, "set")
		if setter ~= nil then
			return setter(self, value)
		end
	end
	return _newindex_0(self, key, value)
end)
_class_0 = setmetatable({
    __init = function() end,
    __base = _base_0,
    __name = "Foo",
    __properties = {
        x = {
            get = function(self)
                print("Getting x")
                return self._x
            end,
            set = function(self, value)
                io.write("Setting x to ")
                yue.p(value)
                self._x = value
                return value
            end
        }
    }
}, {
    __index = _base_0,
    __call = function(cls, ...)
        local _self_0 = setmetatable({}, _base_0)
        cls.__init(_self_0, ...)
        return _self_0
    end
})
_base_0.__class = _class_0
Foo = _class_0
return _class_0

And to test it:

print(Foo, Foo.x)
local instance = Foo()
print(instance, instance.x)
instance.x = "Test"
print(instance.x)

Its output:

table: 0x12341234	nil
Getting x
table: 0xdeadbeef	nil
Setting x to "Test"
Getting x
Test

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions