Implicit Getters and Setters in ColdFusion

Thanks to CF8’s new onMissingMethod method, it’s trivial to implement implicit getters and setters. As easy as it is, I couldn’t google up any code. Since it’s not the kind of thing I’d rather search for than write myself, I thought I’d go ahead and do you the favor and post it here.

I realize there’s a nasty stigma attached and I don’t disagree that it’s bad practice, but it does come in handy when building a proof of concepts or programming exploratoraly.

So here you go, irregardless of whether or not it’s bad practice:

<cfcomponent name="BaseObject">

	<cffunction name="Init" output="no">
		<cfargument name="instance" default="#StructNew()#"/>

		<cfset SetInstance( arguments.instance )/>

		<cfreturn this/>
	</cffunction>

	<cffunction name="OnMissingMethod" output="no">
		<cfargument name="missingmethodname"      required="yes" />
		<cfargument name="missingmethodarguments" />

		<cfset var prefix = Left( arguments.missingmethodname, 3 ) />
		<cfset var suffix = Mid( arguments.missingmethodname,
			4,
			Len( arguments.missingmethodname )
		) />

		<cfif ( CompareNoCase( prefix, "get" ) eq 0 ) and Has( suffix ) >
			<cfreturn Get( suffix )/>
		</cfif>
		<cfif CompareNoCase( prefix, "set" ) eq 0>
			<cfreturn Set( suffix, arguments.missingmethodarguments.1 )/>
		</cfif>

		<cfthrow message="Method #arguments.missingmethodname# not found" />
	</cffunction>

	<!--- private on down --->

	<cffunction name="GetInstance" output="no" access="private">
		<cfreturn variables.instance/>
	</cffunction>

	<cffunction name="Get" output="no" access="private">
		<cfargument name="field" required="yes"/>

		<cfset var instance = GetInstance()/>

		<cfreturn instance[ arguments.field ]/>
	</cffunction>

	<cffunction name="Has" output="no" access="private">
		<cfargument name="field" required="yes"/>

		<cfreturn StructKeyExists( GetInstance(), arguments.field )/>
	</cffunction>

	<cffunction name="Set" output="no" access="private">
		<cfargument name="field" required="yes"/>
		<cfargument name="value" required="yes"/>

		<cfset var instance = GetInstance()/>
		<cfset instance[ arguments.field ] = arguments.value/>

		<cfreturn Get( arguments.field )/>
	</cffunction>

	<cffunction name="SetInstance" output="no" access="private">
		<cfargument name="instance" required="yes">

		<cfset variables.instance = arguments.instance/>

		<cfreturn GetInstance()/>
	</cffunction>

</cfcomponent>

Download it and the MxUnit Tests!