• A Better RandRange()

    Every CFML engine I can find - Adobe ColdFusion 10, 11 and 2016, Lucee 4.5 and 5 - has a bug where if you try to use randRange() on 231-1 (MAX_INT) it will overflow and give you a negative number. See for yourself: http://trycf.com/gist/726e96e5c5e9498b32a2/acf2016. Here is a better way that supports not only MAX_INT but also MAX_LONG (263-1).

    Read more

    comments

  • Setting a minimum request timeout in CFML

    You rarely want to set a request timeout to a particular value - meaning that you want it to time out if it takes a certain amount of time. What you do want is to declare that a particular process might take at least some amount of time to complete. This is what <cfsetting>’s requestTimeout parameter should be - saying that it is ok if it takes at least this long. A recent example of where I needed this is with running some longer running processes as part of a suite of unit tests. The individual method we are testing might take 60 seconds to run for example - but the entire request might take several minutes - when that method is run as part of a normal request lifecycle then the 60 second request timeout is fine, but when running the unit tests it ends my tests early!

    So here is a method that you can use instead - that will update the request timeout to be the greater of the existing timeout or the new timeout. So it will only ever extend, never shorten.

    <cfscript>
      function setMinimumRequestTimeout (required numeric timeout) {
        var currentTimeout = 0;
        try {
            var requestMonitor = createObject("java", "coldfusion.runtime.RequestMonitor");
            currentTimeout = requestMonitor.getRequestTimeout();
        } catch (any e) {
            //do nothing
        }
        var newTimeout = max(currentTimeout, arguments.timeout);
        writedump(var="setting requestTimeout to #newTimeout#");
        setting requestTimeout=newTimeout;
      }
    
      setMinimumRequestTimeout(10); //if the timeout is 60 seconds it will not be updated
      setMinimumRequestTimeout(1000); //the timeout will be updated to 1000s
    
    </cfscript>

    Credit to Brian Ghidinelli.

    comments

  • Find duplicate IDs in your DOM

    With a dynamic application with lots of shared templates it can sometimes be easy to use the same ID for two different elements on the same page. Sometimes this can manifest itself by your JS not working quite right but it isn’t apparent what the problem is. Here is a quick script you can paste into your console to report any duplicates.

    var allElements = document.getElementsByTagName("*"), allIds = {}, dupIDs = [];
    for (var i = 0, n = allElements.length; i < n; ++i) {
      var el = allElements[i];
      if (el.id) {
      	if (allIds[el.id] !== undefined) dupIDs.push(el.id);
      	allIds[el.id] = el.name || el.id;
        }
      }
    if (dupIDs.length) { console.error("Duplicate ID's:", dupIDs);} else { console.log("No Duplicates Detected"); }

    Math Busche covered the same topic last year, head over there to see how he tackled the same thing.

    comments

  • CFML Value Array

    Occasionally in the CFML Slack channel (and the IRC room before it) someone asks about a valueArray() function - what they mean is that they want something like the terribly named valueList() that you can provide a query and a column and get a column slice which will return an array instead of a CFML list. valueArray() exists on Lucee but for ACF you’re stuck implementing it for yourself. Here is a way to do that properly (it’s easy to do it naively wrong).

    Read more

    comments

  • kth Percentile in CFML

    I recently needed to analyze some data in CFML where there was a wide range of values but some real outliers - latency numbers for example. So I ported this kthPercentile() function. You pass in the percentile and an array of numbers - kthPercentile(99, [...]) will give you the 99th percentile for example - kthPercentile(50, [...]) is the same as the median.

    <cfscript>
    	function kthPercentile (k, data) {
    		if (k > 1) { //this allows users to pass in .99 or 99
    			k = k / 100;
    		}
    		arraySort(data, "numeric");
    		var kth = k * arrayLen(data);
    		if (kth == ceiling(kth)) { //its a whole number
    			return data[kth];
    		} else {
    			return (data[int(kth)] + data[ceiling(kth)]) / 2;
    		}
    	}
    </cfscript>

    comments