Thursday, 9 April 2015

Lucee 5 beta: property access

G'day:
First things first: Micha et al have been doing a great job of addressing the issues I had raised over the last coupla days. Most of them have been dealt with, and apparently there'll be a new drop of the beta released today. And the fixes are already in source control for those that like doing their own builds. That's impressive. I've also taken them to task slightly over inaccuracy of the beta release docs, as it's wasted a bit of my time, which I don't appreciate. Micha said he's taken that criticism onboard, which is cool (esp as I was pretty blunt about it). Let's see how that goes.


Anyway, onto the next feature. Lucee 5 adds the ability to be able to specify access modifiers to variables in a CFC. You'll be familiar with these on methods, but now one can do it on variables too. The docs for this are "to the point": "Access Modifiers for variables". Below is an example. It's important to nopte the file strucure for these files, which is as follow:

/base/
    /api/
        /packageA/
            A.cfc
            C.cfc
        /packageB/        
            B.cfc
Application.cfc
test.cfm


// A.cfc

component {

    public this.publicVar = "the outside world can see this"
    private this.privateVar = "the outside world cannot see this"
    package this.packageVar = "other components in this package can see this"

}

This file just sets some variables with the various different access modifiers. Other files in the test will access these.

// B.cfc
component {

    function f(){
        var a = new api.packageA.A()
        return a.packageVar
    }
}

So this tries to access a package-access variable from a different package. We'd expect this to fail.

// C.cfc
component {

    function f(){
        var a = new api.packageA.A()
        return a.packageVar
    }

}

And this tries to access a package-access variable from the same package. We'd expect this to be OK.

The code below just puts all this to the test:

// test.cfm
a = new api.packageA.A()

runSafe("How variable access is reflected in a dump", ()->dump(var=a))

runSafe("Testing visibility of a public property from calling code", ()->echo(a.publicVar))

runSafe("Testing visibility of a package property from calling code", ()->echo(a.packageVar))

runSafe("Testing visibility of a private property from calling code", ()->echo(a.privateVar))


b = new api.packageB.B()
runSafe("Testing visibility of a package property from a different package", ()->echo(b.f()))

c = new api.packageA.C()
runSafe("Testing visibility of a package property from the same package", ()->echo(c.f()))


function runSafe(message, task){
    echo("<h3>#message#</h3>")
    try {
        task()
    } catch (any e){
        echo("#e.type# #e.message# #e.detail#")
    } finally {
        echo('<hr>');
    }
}

The runsafe() function just tidies up the code a bit, so I don't have a whole bunch of try/catch code everywhere.

Note how I'm using lambdasarrow functions to define the callbacks :-)

And the output:


This is all A-OK!

I've not much else to say on this: it's a fairly minor feature. Good work, Lucee Team.

Once this new release is out, I'll revisit the static and abstract stuff to provide some working examples. Hopefully I'll be able to do that this evening.

Righto.

--
Adam