More URI-Related UDFs

To follow up my parseUri() function, here are several more UDFs I've written recently to help with URI management:

  • getPageUri()
    Returns a struct containing the relative and absolute URIs of the current page. The difference between getPageUri().relative and CGI.SCRIPT_NAME is that the former will include the query string, if present.
  • matchUri(testUri, [masterUri])
    Returns a Boolean indicating whether or not two URIs are the same, disregarding the following differences:
    • Fragments (page anchors), e.g., "#top".
    • Inclusion of "index.cfm" in paths, e.g., "/dir/" vs. "/dir/index.cfm" (supports trailing query strings).
    If masterUri is not provided, the current page is used for comparison (supports both relative and absolute URIs).
  • replaceUriQueryKey(uri, key, substring)
    Replaces a URI query key and its value with a supplied key=value pair. Works with relative and absolute URIs, as well as standalone query strings (with or without a leading "?"). This is also used to support the following two UDFs:
  • addUriQueryKey(uri, key, value)
    Removes any existing instances of the supplied key, then appends it together with the provided value to the provided URI.
  • removeUriQueryKey(uri, key)
    Removes one or more query keys (comma delimited) and their values from the provided URI.

View the source code.

Now that I have these at my disposal, I frequently find myself using them in combination with each other. E.g.:

<a href="<cfoutput>#addUriQueryKey(
	getPageUri().relative,
	"key",
	"value"
)#</cfoutput>">Link</a>.

Let me know if you find any of these useful.

In other news, this cracked me up.

parseUri: Split URLs in ColdFusion

Update: I've added a JavaScript implementation of the following UDF. See parseUri: Split URLs in JavaScript.

Here's a UDF I wrote recently which allows me to show off my regex skillz. parseUri() splits any well-formed URI into its components (all are optional).

The core code is already very brief, but I could replace everything within the <cfloop> with one line of code if I didn't have to account for bugs in the reFind() function (tested in CF7). Note that all components are split with a single regex, using backreferences. My favorite part of this UDF is its robust support for splitting the directory path and filename (it supports directories with periods, and without a trailing backslash), which I haven't seen matched in other URI parsers.

Since the function returns a struct, you can do, e.g., parseUri(uri).anchor, etc. Check it out:

See the demo and get the source code.

REMatch (ColdFusion)

Following are some UDFs I wrote recently to make using regexes in ColdFusion a bit easier. The biggest deal here is my reMatch() function.

reMatch(), in its most basic usage, is similar to JavaScript's String.prototype.match() method. Compare getting the first number in a string using reMatch() vs. built-in ColdFusion functions:

  • reMatch:
    <cfset num = reMatch("\d+", string) />
  • reReplace:
    <cfset num = reReplace(string, "\D*(\d+).*", "\1") />
  • reFind:
    <cfset match = reFind("\d+", string, 1, TRUE) />
    <cfset num = mid(string, match.pos[1], match.len[1]) />

All of the above would return the same result, unless a number wasn't found in the string, in which case the reFind()-based method would throw an error since the mid() function would be passed a start value of 0. I think it's pretty clear from the above which approach is easiest to use for a situation like this, and it would be easy to envision scenarios where this functionality could more drastically improve code brevity.

Still, that's just the beginning of what reMatch() can do. Change the scope argument from the default of "ONE" to "ALL" (to follow the convention used by reReplace(), etc.), and the function will return an array of all matches. Finally, set the returnLenPos argument to TRUE and the function will return either a struct or array of structs (based on the value of scope) containing the len, pos, AND value of each match. This is very different from how the returnSubExpressions argument of reFind() works. When using returnSubExpressions, you get back a struct containing arrays of the len and pos (but not value) of each backreference from the first match.

Here's the code, with four additional UDFs (reMatchNoCase(), match(), matchNoCase(), and reEscape()) added for good measure:

See the demo and get the source code.

Now that I've got a deeply featured match function, all I need Adobe to add to ColdFusion in the way to regex support is lookbehinds, atomic groups, possessive quantifiers, conditionals, balancing groups, etc., etc.…

Hot Naked Sushi Action

Someone was telling me yesterday about how ancient and wonderful an art form nyotaimori (aka naked sushi) is. This may or may not exactly (wikipedia.org) be true, but it did get me looking online for more information. The practice has actually been outlawed in China (bbc.co.uk), but then the Chinese don’t allow snoring in the military or cooking children’s arms (mainichi-msn.co.jp) either. Communists.

Fortunately for the sophisticated misogynist, there are a few establishments Stateside that offer nyotaimori, most famously Gary Arabia’s (globalcuisinecatering.com) Global Cuisine (aolcityguide.com) in LA.

I spent a few minutes searching for local spots, and according to ClubZone.com, CafĂ© Japone (clubzone.com) in Dupont Circle does naked sushi Saturday nights. Hmm… why haven’t I heard about this before? I’m skeptical. If it is true, however, I may have to pay them a visit, being a fan of both sushi and naked women.

Thinking…I'm sure they have rules about not talking to the models, but really, where would a conversation with someone you were eating off go?

Me: So… Sushi… you a big sushi person?
Table: Well, not really.
Me: Ah. Well. Being a table, then. How's that working out for you?
Table: Not too bad. Pays the rent. I, uh, go home smelling like fish though.
Me: Oh.

…It could go on like that for a very long, awkward time.

Although I haven’t tried eating off a naked woman yet, I have on many occasions ea…… [Post interrupted by Poor Taste Alert®]

World RPS Society

Check it: Worldwide Governing Body of the Sport of Rock Paper Scissors (worldrps.com).

World RPS Society - Lead on with your rock paper and scissors

This has to be one of the most unintentionally funny sites ever. Check out, for example, their 2002 dedication to the Official Year of the Rock (in particular, check out the last two photo captions within the article).

At first glance, the rules of Rock Paper Scissors seem simple. As you look deeper, however, they’re still pretty simple. Let’s not kid ourselves.

  • Rock smashes scissors (rock wins)
  • Scissors cut paper (scissors win)
  • Paper covers rock (paper wins)
  • Flounder slaps penguin (flounder wins … for expert use only)

…Or so I thought. Here is the 3-page How to Play – Quick Start, and the 7-page must read for all aspiring RPS gurus: Advanced RPS tactics.

Check out this excerpt from the World RPS Society, showing just how high-demand of a sport Rock Paper Scissors can really be:

… In other events, Chad Leatherstep (Co-Chair Disciplinary Committee) in his address delivered a landmark speech pledging a crackdown on performance enhancing drugs in professional level play. “It is the worst kept secret that the dressing rooms at many tournaments have become literal ‘hotboxes’ of abuse. We will be targeting specific suspicious players for random drug testing. They should be easy to spot as they tend to spend more time hanging around the vending machine and concession stands than the drug-free players.”

Imagine that. Your friendly, local Rock Paper Scissors tournament, unbeknowest to you, might have become a literal “hotbox” of performance-enhancing drug abuse!

It makes sense in a way, I guess … these people have to be on something potent to be at an RPS tournament in the first place.

Related stuff:

Your rock, Your paper, Your scissors, Will bring us victory

And here’s some stirring RPS haiku gleaned from the RPS Society’s Bullboard:

You delayed your prime
Won’t synchronize your rhythm
That’s just dirty play

Always throw paper.
How can you lose with paper?
Forget scissors, man.

Paper is the throw
For the narcissistic fool
The masturbator

Few are perfect forms
The rock however is one
Likewise breasts are too