Wednesday 29 April 2015

M

Lucee: issue tracker has moved to Jira

G'day:
Well here's some good news - which happened to catch me out last night - Lucee have completed the switch from BitBucket to Jira for their issue tracking.

They've mentioned it on the Lucee Google Group - Issue Tracker now moved to JIRA - but not on their blog yet, so I figured I'm mention it here. The new URL is: https://luceeserver.atlassian.net/

Tuesday 28 April 2015

Lucee has a new forum expressly for discussing language features

G'day
This is potentially promising from the Lucee mob:

Lucee Language Forum

We've set up a new forum to better manage ongoing discussion about Lucee internals; hacking on the server itself, language specifications and implementation details.

http://lang.lucee.org

"Lucee Lang" is the home for discussing everything related to the implementation and design of the Lucee programming language and CFML compatibility layer. It will also be the home of the Lucee Technical Advisory Group and its deliberations.

Sunday 26 April 2015

CFML: and, for that matter: not everything that looks like a struct actually is a struct

G'day:
Coincidentally very similar issue (to "CFML: just cos something looks like an array doesn't mean it is an array") came up on Friday.

CFML: just cos something looks like an array doesn't mean it is an array

G'day:
One of my Aussie chums hit me up the other day, asking me for some help with some quirky code he was seeing. We worked out what the issue was, but it stands repeating because it was non-obvious from a CFMLer's point of view.

Saturday 25 April 2015

PHP: Silex Controller Providers

G'day:
I'm getting to this earlier than expected (see my observation in yesterday's article: "PHP: Service Providers with Silex")... I was able to write the code last night whilst watching telly, and now I'm stuck on a train due to "signal failure", so have a few (hopefully just a few ~) minutes to start writing this on my phone. Apologies for any autocorruptions I miss during proofreading.

OK, so what's a Controller Provider. Well, for about the first thousand times I read the docs, I could still not answer that. Obviously one can kinda guess from the name: it provides controllers. Ooookay... but what's the ramifications of that, and why would I choose this approach to "providing controllers" over any other way? Obviously it seems to be Silex's prefers way, but they need to do a better sell job on me than that. But the docs weren't doing it. Furthermore, there's bugger-all useful material out there about them (that I could find, anyhow). All the articles I found just regurgitated the docs, or paraphrased them. And the docs just explain "how", but never really explains "why". This is a failing of a lot of docs... explaining the "how" or "what" is easy, but it's the "why" that's important for a given feature. Explain the "why" first, then the "what". Why do I care about this thing you're banging on about? If I'm left with "err... dunno?", that's a fail.

Thursday 23 April 2015

Help Indy

G'day:
I probably should have got onto this earlier, as it's the last day this funding campaign is running, but... err... didn't think about it.

Indy is a fella I follow on Twitter... he's part of our CFML community. He's one of the brightest potentials in New Zealand's IT industry, as demonstrated by his application Parent Interviews. He's been working on this since he was still at school (he's in second year @ uni now, I think), and has got himself onto the tech radar in New Zealand as one to watch ("Website graduates to take on world").

Indy's 19.

Anyway, he's after some $$$ to expand his horizons, and I reckon he deserves the encouragement.

I've just flicked him some money myself, and I know perennial CFML community member Kai has too.

Go on. It's worth it. But hurry up... the campaign finishes today I think.

URL: https://www.pledgeme.co.nz/investments/81-parent-interviews.

Please also circulate the word:


--
Adam

Wednesday 22 April 2015

That CFML book I claimed to be writing...

G'day:
Yesterday Daniel asked me for an update on this "Learn CFML..." book I'm supposedly writing:

The news isn't very impressive, I'm afraid.

I haven't done a commit to it since [checks Github]... March 16, and the current status is that I've got five chapters at "first draft" level, and two chapter in progress. That's out of notionally 24 chapters in total.

I had a completely writing motivational slump when I was over in NZ, through until a week or so ago, but this seems to have passed now. But this means I have a backlog of stuff to write down for this thing, and then once I catch up I'll go back to the book-writing.

It had become a bit of a pain in the arse and a bit demoralising because trying to write about using CFML in a platform-neutral but still coherent fashion is actually a bit tricky. There's really quite a lot of difference between ColdFusion and Railo / Lucee's CFML, and I really don't want to get too bogged down explaining that sort of shite. Also I was finding an awful lot of bugs in both platforms as I progressed. Often a bug will take a coupla hours to clearly and portably reproduce, which just kills my flow. I could simply not raise the bugs, but that's not very helpful.

I'm also waiting hopefully that Lucee might solve some incompat issues that I'd really rather not have to expose them for, as Lucee is my preferred dialect of CFML. It's just a shame they do some stuff quite differently from ColdFusion in place.

Oh, that reminds me. I hit Lucee up about a shortfall I saw in one of their features (I must actually write this up too), and it took about a week to go round the houses with them on the forums and the end result was f***-all other than me questioning... well: a number of things. So that didn't help. That was the point at which I stopped writing completely.

Prior to that I was actually considered going "you know what? Screw ColdFusion, I'm gonna write this about using Lucee's dialect of CFML only". I'm still mulling this over. That said, I first started thinking that a few weeks ago and... well... if you've been keeping apace of things, you might know that I'm hesitant about that being a worthwhile horse to back any more. I'm def on "watch this space" mode @ the moment.

So not a great deal of progress, but I do intend to get back to it. Plus Daniel's made me feel guilty now (nice one, Daniel :-| ;-), so I might try to pull finger and start chipping away again.

Anyway, that's me lunchbreak finished, so I better crack on with some PHP.

--
Adam

PHP: Service Providers with Silex

G'day:
I'm still being obstructed by train delays... I'm now sitting at the station awaiting a train to Leytonstone, at which I can apparently change trains to continue my journey - albeit at snail's pace - into work. I'm hoping I get there in time for the Sandwich Man doing his rounds at 11am.

Anyway, recently I've got myself up to speed with the notion of service providers, in Silex. Silex is the framework we use for the reimplementation of the HostelBookers.com website. Previously I wrote an article ("PHP: messing around with Silex, Pimple & Guzzle") about how we were using Pimple in Silex to handle our dependency injection. At that time we were hand-rolling our usage of it, thus:

Tuesday 21 April 2015

PHP: unit testing private methods... PHP 5.5 version

G'day:
The Central Line isn't running at the moment and the buses are all shagged due to everyone wanting now to catch one, so I've given up trying to get to work and gone home until things settle down a bit. Not wanting to be completely useless to my employers, I've decided to solve an issue I created yesterday by recommending using some PHP 5.6-only code on out 5.5 environment. Duh.

Monday 20 April 2015

Lucee 5 beta: Follow-up to a direct question about createObject()

G'day:
This is still going 'round the houses: "Lucee 5 beta: a direct question about createObject()". Here's my latest follow-up, just FYI.

>5

G'day:
I don't often directly mention my day job or my employer on this blog, but it seems relevant to what I'm up to today, so I'll break form.

Today I start my sixth year at HostelBookers.com. This is the longest period of time I've ever been in one position (I split my time at Straker NZ and Straker UK as different roles, as the jobs were quite different).

Sunday 19 April 2015

PHP: unit testing private methods (a bit of reflection)

G'day:
Yes, I still do PHP as well as Lucee. Well, indeed, I don't do Lucee, I just seem to "invest" my time blogging about it. I am very much doing PHP all day every day again now.

Recently I revisited the notion of unit testing private methods. I realise a lot of people poopoo this notion as one is only supposed to unit test the interface, so only public methods. However when doing TDD, one needs to maintain one's private methods too, so this means one needs to test the behaviour of the change before making it.


Some argue these days that one should not have private methods: having them suggests bad class composition and a private method should be a public method of another class. I can see where they're coming from, but I also suspect the person deciding this was a Java developer and revels in the theory of OO put into practice, rather than... you know... getting shit done. I am in the "getting shit done" camp. I see no benefit in making classes for the sake of it, and I also like the idea of having code as close as possible to where it'll be used. So private helper methods have their place. And they need to be tested whilst being developed.

Others make the very good point that what actually needs testing is the nature of the impact on the result of the public method is what's important, so a private method ought to be tested "by proxy": call the public method, give it inputs that will invoke the to-be-developed new behaviour, and don't care - at test level - where the code happens to be. I have come to appreciate this idea, and it's how we approach a lot of our testing now.

One hitch with this is sometimes it's difficult to only hit the new functionality without also having to horse around appeasing other bits of functionality on the way through. Mocking makes this a lot easier, but not everything can be mocked, and even mocking stuff can be time and effort consuming. I guess if our code was perfect we'd not have this issue so much, but it's not (we're not), so we need to deal with that reality.

Sometimes it's just bloody easier to test a private method.

Back in my CFML days this was piss-easy. MockBox comes with a method makePublic(), which simply makes a private method public. It achieves this by injecting a proxy into the object under test which is public, and this wraps a call to the private method. One then calls that proxy in one's test.

Using makePublic() is as easy as:

mockbox.makePublic(object, "methodName");

Then continue to call methodName as per usual in one's tests. Cool.

This ain't so easy in PHP. One cannot just inject proxy functions into one's methods. However one can use reflection to make changes to an object's existing methods, including its access restrictions.

So what I set out to do was to make my own makePublic() method.

I arrived at this:

private function makePublic($object, $method){
    $reflectedMethod = new \ReflectionMethod($object, $method);
    $reflectedMethod->setAccessible(true);
    return $reflectedMethod;        
}

(it's private as it's just inline in my test class, the entire code for which can be seen here: SomeClassTest.php SomeClass.php).

This is simple enough. However actually using it is inelegant compared to the MockBox approach:

/**
@covers isIndexedArray
*/
function testIsIndexedArray(){
    $testValue = [53,59,61];
    $exposedMethod = $this->makePublic($this->testObject, 'isIndexedArray');
    $actual = $exposedMethod->invoke($this->testObject, $testValue);
    $this->assertTrue($actual);
}

That's no so clear.

So I decided to abandon that approach, instead coming up with this method:

private function executePrivateMethod($object, $method, $arguments){
    $reflectedMethod = new \ReflectionMethod($object, $method);
    $reflectedMethod->setAccessible(true);

    $result = $reflectedMethod->invoke($object, ...$arguments);
    return $result;        
}

This does the same thing, but it looks far more understandable in the calling code:

/**
@covers isIndexedArray
*/

function testIsIndexedArray_withAssociativeArray(){
    $testValue = ['a'=>67,'b'=>71,'c'=>73];

    $actual = $this->executePrivateMethod($this->testObject, 'isIndexedArray', [$testValue]);
    $this->assertFalse($actual);
}

It's really clear what executePrivateMethod does, I reckon.

I'mm going to show this to the lads at work tomorrow, and see what they think. Note: my position in general will be to test via the public interface, but in those situations where this is going to be a lot of work, or make the testing unclear, hopefully we can use this instead.

Thoughts?

--
Adam

Saturday 18 April 2015

CFML: initmethod and CFC inheritance

G'day:
This was supposed to be one of three PHP articles I have up my sleeve and need to write, but whilst testing some Lucee stuff I came to be thinking about this. That said, this is a general CFML question, not a Lucee one.

Lucee 5 beta: a direct question about createObject()

G'day:
In an attempt to get a direct straight answer out of Micha regarding createObject() and loadComponent(), I have posed a very direct question about it on the Lucee Google Group:

Friday 17 April 2015

Lucee 5 beta: new beta 5.0.0.44

G'day:
The Lucee Team are continuing to have a pretty good release cycle with the beta updates: 5.0.0.44 has just been pushed out. There's a few things I raised in there which is pleasing. It's only quite a small release - eight issues fixed - but this is cool when the release cycle is so short.

The release notes were posted to the Lucee Google Group - "New Beta Release (5.0.0.44)" - but they're short enough for me to copy and paste here:

Lucee 5 beta: .lucee files

G'day:
I held off on this one hoping more information would come through from LAS, but I've run out of other documented features to look at, so here we are.

Lucee has added a new "language" to their engine, which is a dialect of CFML.

Thursday 16 April 2015

Lucee 5 beta: tag attributes fix

G'day:
Here's another quick one. I'm waylaid at work and have a few minutes to spare between one hold-up and the next one.

One of the most stupid things about the way CFML tags are processed is that in this tag:

<cfinvoke method="f" arg1=m arg2=n>

The tokens m and n are treated as strings. IE: the literal strings "m" and "n".

Lucee 5 beta: <cfloop> tweak

G'day:
There's another few odds 'n' sods with the Lucee 5 beta that are testable / demoable, but they're pretty trivial / small features, so I'll have to do a series of "misc" blog articles.

There's a bunch of more significant stuff I have not looked at yet because there's no beta documentation for them, so I cannot work out what to do. It's been observed that I am being unhelpful to the Lucee project for making observations like this, interestingly enough. I'm not one to get all biblical (although perhaps I should, but in a different sense), but Matthew 7:3 definitely spring to mind here. But anyway, whatever [gallic shrug].

OK, so they've added a new feature to <cfloop>, anyhow.

Wednesday 15 April 2015

Lucee 5 beta: abstract (redux)

G'day:
Right, after a bit of a false start with the abstract support in Lucee (ie: they forgot to release it in the 5.0.0.42 version, when I first tried it - "Lucee 5 beta: abstract components (abject fail now fixed)"), it's now all working (as of 5.0.0.43). So I'll revisit with an example to demonstrate its behaviour.

A while back I looked at how PHP dealt with abstraction: "Looking at PHP's OOP from a CFMLer's perspective: inheritance, static & abstract, interfaces", and I have taken that code and converted it to CFML and will use that as an example. It's interesting how close the code is between languages. CFML is a bit cleaner though.

Survey results: A quick OO terminology survey

G'day:
I didn't quite get 100 responses, but 95 is close enough (and not bad for over a weekend, during which this blog's readership is pretty dire).

To recap, the first two questions related to this code:

x = new Y()

First I asked whether you were more likely to describe x as:

  • a class
  • a component
  • an instance
  • an object
  • or something else

Second I asked the same question of Y.

The third question was to guess what a CFML function createComponent() might be for.

Tuesday 14 April 2015

ColdFusion Team & especially Anit: bloody well done

G'day:
This is a quick adjunct to the article I put up a few min ago: "ColdFusion 10 & 11: new updaters released".

During install, Ray found that the update didn't show up in his CFAdmin. Anit reported back straight away:



And before you knew it, he was reporting back:


Elapsed time: 17 minutes.

Good work, Adobe ColdFusion Team. And good being so responsive, and keeping us in the loop, Anit.

Righto.

--
Adam

ColdFusion 10 & 11: new updaters released

G'day:
This just came to my attention courtesy of Ron Stewart on Twitter:


Monday 13 April 2015

Lucee 5 beta: the PHPification of CFML

G'day:
I continue to raise my eyebrow at some of the decisions the Lucee Team have been making regarding work they've been doing in Lucee.

Lucee 5 beta: final keyword (redux)

G'day:
Community stalwart and "OK bloke even if he is Australian" Andy Myers made an observation on Twitter this morning:

This is a good question, and one I did not think to check.

Lucee 5 beta: final components and methods

G'day:
I guess I need to go back and have a decent look at abstract components and methods at some stage, after my abortive first attempt ("Lucee 5 beta: abstract components (abject fail now fixed)"). But in the mean time, I'll look at the "opposite": final components and methods.

If one flags a component or method as final, then the intent is that that component or method cannot be extended by a sub component (or a method in same). This is a common feature in OO languages, although was never initially implemented in CFML's OO implementation. I really question the merits of adding it to CFML now, really. Beyond the idea that "well it should have been there", it's kind of only relevant for people building APIs, which doesn't often happen in CFML, and I've always found usage of final to be a pain in the arse more than anything actually useful. My position is I should be able to extend any class I like: it's not for the author of a class to pre-decide how I might end up using it.

Saturday 11 April 2015

Lucee 5 beta: createComponent()

G'day:
I'm moving away from Lucee 5's new additions to CFC implementation today, and having a look at one of the new functions they've added: createComponent(). Before clicking that link or reading on: try to guess what the function does.

CFML: A quick OO terminology survey

G'day:
If you have 5min (and it probably won't even take that long), do you fancy filling out a quick survey: "CFML nomenclature"?

The survey asks three questions, based on this code snippet:

x = new Y()

Basically I want to know how you'd refer to x, and how you'd refer to Y. Don't answer here, answer on the survey. As I note on the survey: they're not trick questions, and I'm not looking for people to demonstrate how clever they might think they can be. I'm just after your honest answers.

As per usual, I'll report back once I get enough responses to warrant it.

Oh, and if you could help me circulate word about this, that'd be well cool. Cheers:


Cheers.

--
Adam

Friday 10 April 2015

Lucee 5 beta: class constructor

G'day:
This article stems from me being slow on the uptake. In the hope I'm not the only thick person out there, I'm gonna document my intellectual failings in case there are other daft ppl out there.

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

Wednesday 8 April 2015

Lucee 5 beta: abstract components (abject fail now fixed)

G'day:
I was gonna spend my lunchtime having a look at abstract classes / methods in Lucee 5 ("Abstract/Final components/functions"), but... well it didn't work out.

Update:

It is important to note that Micha jumped on the case with this situation straight away, and it is now fixed in Lucee 5.0.0.43. I was testing on .42. It was fixed in less than 24 hours, and that is very impressive. Keep up the good work, Lucee Team.

So it's import to note that all the code in this article now works fine, despite the comments to the contrary that I make.

Lucee 5 beta: "lambda" syntax

G'day:
Right, so the second thing I'm gonna look at (after yesterday's "Lucee 5 beta: static methods & properties") is Lucee's new "Lambda" syntax.

This syntax is simply a more terse syntax for defining functions using function expressions. TBH, it's not very interesting.

Tuesday 7 April 2015

Lucee 5 beta: static methods & properties

G'day:
So Lucee 5 beta is out, and I decided to have a look at some stuff this evening.

One of the good things in Lucee 5 is that it will support static methods and properties. This should have been in CFML since CFMX6, so it's high time it was added to the language.

I'm gonna have a quick look at how this stuff has been implemented.

Lucee 5 public beta is out...

G'day:
That's about all I have to say. I just saw the Twitter message now:


And I am downloading it now.

I don't think I have much time to look at it tonight (shattered, have had two beers already and the prospect of a DVD seems too compelling), but I'll attempt to focus my non-work time for the next few days having a look and reporting back.

Still: this is great news for Lucee, eh?

Good work, Lucee peeps.

--
Adam

Lucee 5 beta this week?

G'day:
So... three weeks ago, Andrew Dixon (speaking on behalf of the Lucee Association), said we'd have a Lucee 5 beta in 2-4 weeks.

Just a heads-up, Lucee bods... we're into that fourth week now. Are you still on track to get the public beta out the door this week?

Update:

This has just been confirmed by Alex: it's still due to be out the door this week. Nice one.

Rather looking forward to seeing it, me.

(and, no, I have nothing insightful to add. This is just what occurred to me on the train on the way in this morning. Back to PHPland now).

--
Adam

Sunday 5 April 2015

PHP: new to me: the ... "operator"

G'day:
OK, so I'm back in PHPland, and as luck would have it I encountered two new interesting things this week. New to me, anyhow. This is actually the one I found second, but as it's part of the solution for the other one, I'll write this one up first.

Now people are are au fait with PHP need to remember I'm a newbie @ PHP, so this article will be shy of any real insight... it's just me teaching myself stuff.

Saturday 4 April 2015

CFML: using an array as an argument collection

G'day:
Here's a quick one for Lucee users (this does not apply to ColdFusion).

I discovered yesterday (? maybe the day before) that as well as taking a struct for an argument collection; Lucee will also take an array. This is a piece of the argument collection puzzle that has been missing from CFML for quite some time. That said,  I dunno how long Lucee/Railo has supported this..? It's def only "new to me", rather than "new", per se.