This is not the function you are looking for

This post is more than 2 years old.

Yesterday I was doing some editing on the CFML Reference wiki when I ran across a function that is - as far as I know - one of the most misused functions in ColdFusion. What function is that? listContains.

To be clear, listContains is not buggy. It works 100% as advertised. But in the 15 or so years I've used ColdFusion I have not seen one person use it the right way. Simply put, listContains searches a list for partial matches. So for example, given a list of: ray,scott,dave,adam,data. You want to see if the list of names includes ada. If you use listContains then you will get a false positive match on adam. Maybe you do want that. It can happen. But again, I've never seen someone using listContains that really wanted this.

So folks, please keep this in mind. What we really need is a good ColdFusion Linter to flag stuff like this.

p.s. Thank you to Brad Wood for the image!

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Doug posted on 4/8/2014 at 5:35 PM

Interesting post. I just did a scan of one of my larger projects, and found I hadn't used listContains() once. listValueCount(), however, is used extensively.

Comment 2 by Eric Cobb posted on 4/8/2014 at 8:04 PM

Yeah, I remember running into this a while back:

Comment 3 by MikeZ posted on 4/8/2014 at 9:29 PM

True, I usually pick one of the listFind() methods even when I don't really have a use for the specific index that's returned.

Comment 4 by Nando Breiter posted on 4/9/2014 at 12:28 PM

I've used listContains to very good effect with a permissions system in FW1, allowing either access to the entire section or access to only a specific item. I've found it very useful in this case.

Comment 5 by Raymond Camden posted on 4/9/2014 at 3:59 PM

Nando, I'd like to hear more. Can you share a simple example?

Comment 6 by Nando Breiter posted on 4/11/2014 at 3:53 PM

Years ago, many, I read an article by Hal Helms that advocated using permission keys rather than roles for permissions in an app. The difference is that a set of permission keys are given to a user that define which areas of the app they are allowed to use, or how they are allowed to use them, just as we have keys to unlock doors in the physical world. It makes permissions both more flexible and granular if needed. Users are given only the keys they need, and keys can be added to the system at any time.

I use a list to store permission keys, because it's easy to store in the database, it's dead simple to translate a set of checkboxes that define the permission keys in an app to a list - simply by giving them all the same name, and because listContains() makes the permission key implementation as a list even more powerful.

I use FW/1, but the approach would integrate well with any framework. I create my permission keys to match FW/1's section.item convention. So if I want to give a user permissions to edit employees, I check the corresponding checkbox that gives them the key emp.edit. If I want a user to only be able to view employees, they get the permission key emp.view. As you can imagine, when a User is persisted, the list of permission keys is stored in the User database record, and when a User logs in, the list of keys is stored in session scope.

Both of my sample users need access to the Employee section, so I wrap the navigational element for the Employee section with the simple

<cfif ListContains(session.permission,"emp.")>
<a href="?#framework.action#=emp.list">#rt('Employees')#</a>

and the nav for the employee section is rendered for both.

If a User does not have a single permission to the employee section, the navigational element is hidden and the before method in the controller prevents any access.

For more granular control over a specific key, I use listFind(session.permission,"emp.edit").

If I want to move toward role-based security, for "Editors" as a contrived example, I could use ListContains(session.permission,".edit")

As I said, I've found ListContains() to be very useful in this context.

Comment 7 by Raymond Camden posted on 4/11/2014 at 8:15 PM

Cool - thanks for sharing this. I remember that article actually.