Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with: Matthew Abbott and Andrew Abbott and Chuck Leverette
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with: Matthew Abbott@abbottmw ) , Andrew Abbott , and Chuck Leverette

Sort Only Works With directoryList() When ListInfo Is Query In Lucee 5.2.9.31

By Ben Nadel on
Tags: ColdFusion

When calling the ColdFusion function, directoryList(), you have the option to sort the underlying data-structure by column (ex, "directory ASC"). With Adobe ColdFusion, this works regardless of the return type (listInfo). With Lucee CFML, on the other hand, the sort argument is only applied if the listInfo is "query." This divergence in behavior is called-out on the CFDocs.org site (thank you Shawn Grigson); however, since I ran into this problem yesterday and could not find any information about it via Google, I wanted to clearly articulate the problem for my future self.

To see this behavior in action, let's look at the following recursive directoryList() call:

  •  
  • paths = directoryList(
  • expandPath( "./demo" ),
  • true, // Recurse.
  • "path", // Return a list of full file-paths.
  • "*.txt",
  • "directory ASC, name ASC"
  • );
  •  
  • writeDump( removePathPrefix( paths ) );
  •  
  • // ------------------------------------------------------------------------------- //
  • // ------------------------------------------------------------------------------- //
  •  
  • /**
  • * I remove the long, common prefix for the paths so that the data is easier to
  • * visualize in the demo.
  • *
  • * @paths I am the collection of paths being simplified.
  • * @output false
  • */
  • public array function removePathPrefix( required array paths ) {
  •  
  • var slimPaths = [];
  •  
  • for ( var path in paths ) {
  •  
  • arrayAppend(
  • slimPaths,
  • replace( path, "/Users/ben/Sites/bennadel.com/testing-commandbox/lucee-dir-list/", "/" )
  • );
  •  
  • }
  •  
  • return( slimPaths );
  •  
  • }
  •  

As you can see, we're gathering all the files in the "demo" directory, returning the list of "path" values, and then outputting them to the screen. And, here's a side-by-side comparison of the output in Adobe ColdFusion 10 and Luce CFML 5:







 directoryList() sorting works differently in Adobe ColdFusion vs. Lucee CFML when returning



As you can see, the directoryList() function in Adobe ColdFusion adheres to the "sort" argument even when it's only returning the paths. Lucee CFML, on the other hand, ignores the "sort" argument altogether and returns the paths as a collection of opaque string values.

NOTE: If you replace the sort directives "ASC" with "DESC", the Lucee output does not change.

To get the directoryList() sort to work the same in both Adobe ColdFusion and Lucee CFML, you have to use the "query" return type (listInfo). When you use the "query" return type, Lucee will apply the correct "sort" to the data:

  •  
  • directoryInfo = directoryList(
  • expandPath( "./demo" ),
  • true, // Recurse.
  • "query", // Return data as a full query.
  • "*.txt",
  • "directory ASC, name ASC"
  • );
  •  
  • writeDump( extractPathsFromQuery( directoryInfo ) );
  •  
  • // ------------------------------------------------------------------------------- //
  • // ------------------------------------------------------------------------------- //
  •  
  • /**
  • * I extract the "slim path" from the given directory list query.
  • *
  • * @directoryInfo I am the directoryList() query being transformed.
  • * @output false
  • */
  • public array function extractPathsFromQuery( required query directoryInfo ) {
  •  
  • var slimPaths = [];
  •  
  • for ( var record in directoryInfo ) {
  •  
  • var slimDirectory = replace(
  • record.directory,
  • "/Users/ben/Sites/bennadel.com/testing-commandbox/lucee-dir-list/",
  • "/"
  • );
  •  
  • arrayAppend(
  • slimPaths,
  • // The directoryList() query separates the directory value from the
  • // filename value. As such, we have to concatenate the two values in
  • // order to calculate a path that is similar to our last demo.
  • ( slimDirectory & "/" & record.name )
  • );
  •  
  • }
  •  
  • return( slimPaths );
  •  
  • }
  •  

As you can see, we've changed the "type" from "path" to "query". This will get the directoryList() function to return a robust data-structure that contains individual columns for "directory" and "name". Therefore, to get back to the desired single path value, I am looping over the query and concatenating the two column values.

If we run this version, we get the following side-by-side comparison of Adobe ColdFusion 10 and Lucee CFML 5:







 We can get sort to work in directoryList() for both Adobe ColdFusion and Lucee CFML if we return a query type.



As you can see, by using a "listInfo" return type of "query", we get the directoryList() function to return the same values in Adobe ColdFusion and Lucee CFML.

As I said before, this compatibility issue is called-out in the CFDocs.org site. But, yesterday, when this issue started breaking code, I couldn't find anything in Google (searching for things like "lucee directorylist bug" and "lucee directorylist recursive sort"). As such, I just wanted to document the divergent behavior for the next time I get stuck and try to Google for the solution.



Reader Comments

@Igal,

You are a good person -- thank you for doing that. I guess I was hesitant to open a ticket since it appeared to be documented, at least, on the cfdocs.org site. I just chalked it up to a difference that I didn't have on my radar. That said, I'm always for creating consistency!

Reply to this Comment

Thank you for your kind words, Ben.

In most cases we consider incompatibility with ACF to be a bug. This was more of an observation on cfdocs.org, rather than a documented behavior.

Anyway, I am happy to say that the issue is resolved for Lucee 5.3.2.41
https://luceeserver.atlassian.net/browse/LDEV-2152

We will need to discuss whether to port it back to older versions, as it would have a minor potential of breaking someone else's code on a version that is considered stable.

Best,

Igal

Reply to this Comment

@Igal,

I love how fast Lucee moves and how great the Lucee community is and receptive to this kind of stuff. Really just blown away.

We are just about done with our Lucee conversion at work. It's time for me to sit down and really understand how I can leverage Lucee-specific code.

Reply to this Comment

@Sabrina,

Update to the latest 5.3.2.x or at least to Lucee 5.3.2.41 which resolves this issue.

Best,

Igal

Reply to this Comment

@Ben,

That's great to hear!

Feel free to reach out if I can be of help, though it's best to contact me directly or at least in the Lucee forum so that I'll see it in a timely manner.

For some reason I got a notification of Sabrina's comment from today but not for yours from Feb 20th.

Best,

Igal

Reply to this Comment

That's great to hear!

I, too, love the Labmdas. I actually posted about that recently on LinkedIn with a screenshot from my recent talk at ApacheCon: I Love Lucee!

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.