AdobeStock_455007340

Using Scorpio ArgumentsCollection

CFML is a tag based language. When tags need arguments or options passed to them, they are passed as attributes. This is an integral part of what makes CFML so easy and so productive. But sometimes, having to pass attributes can be a hindrance. Consider a simple example, a where you sometimes just need basic attributes (NAME and DATASOURCE perhaps) but other times want additional optional attributes (like USERNAME and PASSWORD). There is no way to conditionally include attributes in a tag, and so you end up having to write code like this:


...



...


It’s just an example, but it’s not pretty at all. And this same is true if you conditionally want to add query caching, or specify an SMTP server in , and so on.
Scorpio solves this problem in the simple and elegant fashion we’ve come to expect from ColdFusion. In Scorpio you can pass all tag attributes as a single structure, an ARGUMENTSCOLLECTION. Here is a simple :




...

As structure members can be added conditionally, passing optional attributes becomes a simple matter of conditionally adding members, as seen here:











...

This new syntax can be used by all sorts of tags, including , , , , , , and many more.

30 responses to “Using Scorpio ArgumentsCollection”

  1. Jim Pickering Avatar
    Jim Pickering

    Ben – you need to increase the font size for your code output in your blog. It is barely readable. We’re looking forward to your visit in Kansas City at KCDevCore.

  2. Ben Forta Avatar
    Ben Forta

    Jim, I am looking at it in FF2 and IE7, and the size if fine. What browser are you using? And on what OS?
    — Ben

  3. Gary Funk Avatar
    Gary Funk

    Ben, the font size is fine on my end too.

  4. Fernando S. Trevisan Avatar
    Fernando S. Trevisan

    Here is the same: font-size is great.
    And amazing feature for Scorpio. Unlike CF7, CF8 will be a must-have upgrade.

  5. Michael Long Avatar
    Michael Long

    How about all of the CFFORM, CFINPUT, and other form tags? And CFQUERYPARAM?
    Would make writing form and ORM code generators s a lot easier.

  6. Ben Forta Avatar
    Ben Forta

    Michael,
    Yep, all CFFORM tags (including CFFORM, CFINPUT, CFSELECT, etc.) and CFQUERYPARAM support this syntax. In fact, it is supported by just about everything except from flow control tags (CFIF, CFCASE) and variable assignment tags (CFSET, CFPARAM) and tags like CFOUTPUT.
    — Ben

  7. Thomas Messier Avatar
    Thomas Messier

    Awesome addition! Is there any plan to add some kind of short syntax for creating arrays and structures? Kind of like in javascript where you can do something as follows:
    var struct = { title: ‘Hello’, content: ‘World’ };
    It just gets pretty repetitive so have to do a bunch of cfsets, ArrayAppends(), etc.

  8. todd sharp Avatar
    todd sharp

    Ben:
    I’m curious why this feature uses argumentsCollection as opposed to the existing argumentCollection shortcut that can be used to pass arguments to a cfc call?
    Is there a reason they’re different?

  9. Ben Forta Avatar
    Ben Forta

    Todd, I raised the same question. Keep in mind that this is still a work in progress.
    — Ben

  10. Chris Phillips Avatar
    Chris Phillips

    Ben,
    Maybe Jim is using FF under Linux. I have been getting set-up under Linux (PCLinuxOS). One of the things I noticed is the code blocks on my blog being quite small. If I have trouble reading anything I just use CTRL-+ and CTRL–.

  11. Tomas Avatar
    Tomas

    for me something did not turn out.

  12. Ben Nadel Avatar
    Ben Nadel

    That is sweeeeeet!

  13. Kyle Hayes Avatar
    Kyle Hayes

    YES! Alright! Another great valuable feature from Scorpio! This is truly going to be an incredible and groundbreaking release!

  14. Nathan Strutz Avatar
    Nathan Strutz

    Ben, Great feature, looking forward to using it!
    Question – Shouldn’t it be AttributeCollection or AttributesCollection instead of ArgumentsCollection? Or like Todd Sharp said, the existing variable we’re already used to typing, ArgumentCollection. Thanks for the teaser – see you on Wednesday!

  15. Mathew Ford Avatar
    Mathew Ford

    Ben,
    Can you mix the two types, i.e. still use the NAME parameter but pass in the others like DSN, USERNAME, PASSWORD, etc via the ARGUMENTSCOLLECTION parameter? Same question for other tags too. I would hope that an argumentscollection member would be used only if there were not a direct parameter specified.

  16. Ben Forta Avatar
    Ben Forta

    Mathew, no, if you use the ARGUMENTSCOLLECTION then it must be the ONLY actual tag attribute. That way there is no ambiguity over which to use if the same attribute is defined in both places.
    — Ben

  17. Mike Kelp Avatar
    Mike Kelp

    Hi Ben, this looks to be a great feature.
    I would like to stress however that this feature remain consistent with both cfmodule and cfinvoke. With both of them, you can pass attributeCollection and argumentCollection attributes respectively along with normal attributes (and cfinvokearguments as well).
    Where I see this losing a lot of value is in the example you posted. I would very likely cache the username and password for cfquery calls in a structure in my application as I do now, but using this new method to pass them in. The problem comes when I want to have different names for all my query and caching when necessary. Having to modify or copy the struct in these cases completely voids the feature.
    Here are the docs I found on the precedence of arguments, which make great sense to me as they are in order of how explicit the arguments are:
    Using hybrid means of passing cfinvoke arguments (explicitly stated precedence)
    http://livedocs.adobe.com/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/html/wwhelp.htm?href=00001051.htm
    Using hybrid attribute passing with custom tags (coded in the example)
    http://livedocs.adobe.com/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/html/wwhelp.htm?href=00001077.htm
    Thanks for sharing and I’m excited to see your presentation tonight at the DFW CFUG!
    Mike Kelp

  18. Christian Ready Avatar
    Christian Ready

    Ben, this is a great addition.
    Regarding the font size issue, any font size set below 0.8em becomes illegible in browsers such as Opera and FF on the Mac. If you change the font-size value from 0.7em to 0.9em in the .code declaration in the style.css file, the fonts will be readable cross-platform.
    Thanks again for telling us about argumentscollection!

  19. Steven Van Gemert Avatar
    Steven Van Gemert

    Thomas Messier raised the question as to whether we can do:
    var struct = { title: ‘Hello’, content: ‘World’ };
    Well, let me tell you that I saw that last night at Ben’s DFW CFUG presentation. You can also do arrays that way too with:
    var array = ["First", "Second", "Third"];
    (I think the syntax is right there). So, yes it will be available in Scorpio if I understood it right. I remember Ben saying that you ought to be able to take existing java declarations and just copy them in – so I guess they have the syntax the same. Good idea if you ask me!
    Steven

  20. Ben Forta Avatar
    Ben Forta

    Thomas, Steven is correct. I did not reply to your message last week as we were not planning to demonstrate this feature until this week. But, see http://www.forta.com/blog/index.cfm/2007/5/1/Implicit-Array-And-Structure-Creation-In-Scorpio.
    — Ben

  21. Thomas Messier Avatar
    Thomas Messier

    This absolutely rules. As small as it seems to be, it’s the kind of thing that saves developers tons of time because we use these functions all the time. I’m thrilled to hear it was added, it shows that the people at Adobe are really paying attention to the things that matter!

  22. Michael Long Avatar
    Michael Long

    I think Mike Kelp is correct in that you need to be able to use attributeCollection AND have extra attributes specified as well. As mentioned, being able to setup a DSN struct isn’t very useful if you can’t easily specify a query name.
    From a precedence standpoint, I’d grab the attributeCollection first, if it exists, then apply any additional attributes that may be present. That seems intuitive to me, and I’d rather have the possibilty of a slight bit of confusion, which can be cleared up by reading the documentation, as opposed to requiring the developer to write addtional lines of code to do structCopys and extra struct assignments just to set a query name.
    Further, it’s pretty well established that tags (and custom tags) have attributes, and some tags already have an attributeCollection. CFFunctions, OTOH, have arguments. Please don’t confuse the issue, and use attributeCollection for the new tag feature.

  23. Steve Nelson Avatar
    Steve Nelson

    Ben,
    With the JSON syntax for the structs/arrays/etc, is there a native tag that will go the other direction? i.e. tag a CF struct and produce json text? Maybe a cfjson tag that works just like cfwddx, but works with json syntax?
    I love the simplicity of wddx, but prefer the smaller raw data size of the json syntax.

  24. Thomas Messier Avatar
    Thomas Messier

    Looks like I got a discussion started in the wrong blog post. Sorry Ben! Steve, I think while the syntax is JSON-esque, it’s not exactly JSON, you don’t use colons for objects/structs, for example. Having said that, native JSON support would be great. Meawhile you can use CFJSON, an open source project at http://www.epiphantastic.com/cfjson (which I maintain), it does exactly what you said.

  25. Steve Nelson Avatar
    Steve Nelson

    Absolutely Thomas, I use it all the time and love it. So much so that i think it should be native to CF.

  26. Rick Root Avatar
    Rick Root

    Man, this is another cool feature… I can see it coming in handy for sure! Especially on the cfquery tag.
    DAMN IT I’m on my 4th attempt at this captcha.

  27. Qasim Rasheed Avatar
    Qasim Rasheed

    I am not sure if anyone else has pointed this but is there is a reason that this special attribute is called argumentCollection and not attributesCollection. attributesCollection is more consistent with how attributes can be passed to regular custom tags

  28. Rick Root Avatar
    Rick Root

    We had an interesting discussion at the triangle adobe user group meeting last night about this regarding whether or not named arguments should override arguments specified in the argumentcollection, or if they should be ignored, or if they should cause an error.
    Tim and Adam took a straw poll, and we mostly voted for "override"… that way you can use an argumentcollection for "default" arguments but you can still override certain arguments if you need to or want to. Like you might have an argumentscollection stored in the application scope that you use as a default for cached queries, but maybe you want to change one attribute for a certain query, like how long a query is cached…
    Damn it, I can *NEVER* get the captcha right the first time on this blog… how about a third time… nope let’s go for four… five..?

  29. Ben Forta Avatar
    Ben Forta

    attributecollection is already used in other tags, so that won’t work. But we’re still looking at this one.
    — Ben

  30. Tony Dolan Avatar
    Tony Dolan

    Just a footnote for the fellow slow witted. It was AttributeCollection they went with in the end:
    So the cfc query code abbreviates neatly to:
    <cfquery ATTRIBUTECOLLECTION = "#REQUEST.query_parameters#" name="getData">
    In the Application.cfc in the onRequestStart function:
    <cfscript>
    REQUEST.query_parameters = StructNew();
    REQUEST.query_parameters.datasource = THIS.DataSourceName;
    if(THIS.database_uses_password){
    REQUEST.query_parameters.username = THIS.DB_Username;
    REQUEST.query_parameters.password = THIS.DB_Password;}
    </cfscript>
    I set all my variables on cfinclude page i.e.app_parameters.cfm using the THIS scope for users with different setups. i.e.
    THIS.DataSourceName = "dsn_name";
    THIS.database_uses_password = True;
    THIS.DB_Username ="db_username";
    THIS.DB_Password ="db_password";
    Being explicit as I went off on a wild goose chase with this issue. Might save some fellow travellers some time.

Leave a Reply