The difference between variables.instance and instance

Trouble shooting some bung code I came across a weird one today. This highlights the need to scope variables.

Quite often for cfc's when storing private instance data developers use a structure called instance under the variables scope or private. You can of course just use variables, but anyway it seems a trend in some code i've been reviewing.

Anyway I suppose it's better than using the this scope as it means the data is private to the cfc instance.

There is however a difference between variables.instance and instance, the test case I created below shows how lazyness can byte you in the arse.

this.cfc --------

<cfcomponent name="test" hint="my test lazy cfc">
<cffunction name="init" returntype="test">
   <cfargument name="datasource" type="string" required="yes">
   <!--- using instance as a scope for private instance data --->
   <cfset instance.datasource=arguments.datasource>
   <cfreturn this>
</cffunction>
</cfcomponent>

test.cfm --------

<cfset testCFC=createobject("component","test").init(datasource="foo")>
<h1>Having a form field named instance breaks my cfc</h1>
<form name="thoughshallscope" action="" method="post">
   <input type="hidden" name="instance" value="oh dear">
   <input type="submit" name="gostuff" value="break my cfc">
</form>
<br>
<a href="?instance=KillthatCFCYeah!!">Having a link with the word instance in isn't good either</a>

This can be fixed by modifying the init method firstly to use variables.instance but secondly to make sure you use structNew() before working on a structure.

<cffunction name="init" returntype="test">
<cfargument name="datasource" type="string" required="yes">
<!--- using instance as a scope for private instance data --->
<cfset variables.instance=structNew()>
<cfset variables.instance.datasource=arguments.datasource>
   <cfreturn this>
</cffunction>

Detecting changes to deep structures/variables/directories

I was looking at Vince Bonfanti's Directory watcher the other day and i was thinking about whether there is an easy way of detecting a change within a deep directory structure.

Which also got me thinking to more complex cf variables and how i could potentially detect a change which in some instances could be many levels deep.

Given the current test code

<cfscript>
stTestStruct=StructNew();
stTestStruct.qTest=QueryNew("col1,col2");
queryAddrow(stTestStruct.qTest);
querySetCell(stTestStruct.qTest,"col1","foo");
querySetCell(stTestStruct.qTest,"col2","bar");
querySetCell(stTestStruct.qTest,"col1","foo");
querySetCell(stTestStruct.qTest,"col2","bar");
querySetCell(stTestStruct.qTest,"col1","foo");
querySetCell(stTestStruct.qTest,"col2","bar");
stTestStruct.foo="bar";
stTestStruct.bar=arrayNew(2);
stTestStruct.bar[1][1]="phew";
stTestStruct.bar[1][2]="bar";
stTestStruct.bar[2][1]="another";
stTestStruct.bar[2][2]="bar";
</cfscript>

I've got a reasonably good test structure (no object instances but hey). What i was considering was using hash to create a unique value for my data. Hash of course works with strings but you can use .toString() methods with Arrays, Queries, Structures

<cfoutput>#hash(stTestStruct.toString())#</cfoutput>

This creates a unique hash representation of my variable, sadly for query objects this doesn't really work, where as a change to the number of records or number of columns would change the hash value if an individual record itself changes it doesn't, this method does however work ok for Arrays and Structures.

So what can work for queries as well ? CFWDDX

<cfwddx action="CFML2WDDX" input="#stTestStruct#" output="test">
<cfdump var="#hash(test)#">

This gives a hash value which we can store in a persistant scope and easily check whether or not the data in stTestStruct has changed. Once of course a change has been detected we then need to go through in the traditional way and find what has.

How could this be used to signal a change to a directory.

e.g.

<!--- look at my entire webroot *notice the recurse attribute --->
<cfdirectory directory="c:\inetpub\wwwroot\" recurse="true" filter="*.*" name="qFiles">
<cfwddx action="CFML2WDDX" input="#qFiles#" output="test">
<cfdump var="#hash(test)#">

Try adding/deleting modifying a file all should result in a new hash value signifying a change.

What server am i using ?

One of the nice things about clustering when its done well is that from the users standpoint you have no idea what machine in the cluster has answered your request.

Unfortunately thats a real pain when you need to know.

cgi.http_host will of course in cfml tell you the host name but if your not redirecting using www1 www2 etc to identify your nodes, then you're out of luck. Actually having access to the server name itself is therefore useful

The code below outputs the actual machine name and works on CFMX, Bluedragon JX/.NET

<!-- I ran on-->
<cfset inet = CreateObject("java", "java.net.InetAddress")>
<cfoutput>#inet.getLocalHost().getHostName()#</cfoutput>

In addition if you're running on CFMX Enterprise (with J-Run) the following code can be useful to tell you what CFMX instance serviced the request.

<cfobject action="create" type="java" class="jrunx.kernel.JRun" name="jr">
<cfset servername = jr.getServerName()>
<cfoutput>Java Server Instance = #servername#</cfoutput>

High Performance CFML platform

I'm sure most people are familiar with LAMP as an acronym for a common platform used to build web applications.

More recently i came across LAMBDA. Now most of the focus here seems to be around producing applications for a low software investment of course using Linux. There doesn't seem to me much about on creating high performance platforms.

[More]

Finding individual file sizes and Dot Net/Java ?

For those developers that are using Java as part of your day to day development with CFMX. Apparently thats not a good enough reason not to try Bluedragon.net you know !!

I had the following code which I was expecting to break on Bluedragon.net so was looking for some equivalent .net classes when to my surprise it ran. It's not alone actually, most of the java libraries i tried ran. This is due to the fact that J# is used to run Bluedragon.net And even your specific java classes can be recompiled into J#.

A good example is

<cfset pathToFile = expandpath("\mydir\myfile.pdf")>
<cfset fileInfo = createObject("java", "java.io.File").init(pathToFile)>
<cfoutput> My PDF file is #round(fileInfo.length()/1000)#K </cfoutput>

Coldfusion Tuning links

I moved this from the resources section of the Pixl8 Interactive web site as now we have an externally facing blog it makes more sense for these Coldfusion MX Tuning links to be here.

[More]

Including other languages using CFML

The flexiblity of Coldfusion is one of the reason i love it as a platform. What other platform allows the ability to combine modules of code written in different languages and have them all execute seamlessly?

We've been working hard to develop our CMS framework into a truly cross platform system so I've been playing a lot with with Bluedragon .NET, Bluedragon JX and of course old faithful CFMX 7. The Bluedragon.NET feature which i'm the most impressed by is the ability to include .aspx pages from CFML and actually have the code execute. More than that in fact Application,Session,Request scopes are all available. And your .aspx pages can call CFCs, UDFs, Custom tags. All very funky.

<cfinclude page="mypage.aspx">

Notice the page attribute which tells Bluedragon 7 that the page being included is a .NET one.

What i'd really like to see is the same ability for Bluedragon JX/J2EE for your java files to actually be able to do the same, accessing the CFCs, UDFs, CFML custom tags.

You can of course currently on the Java based versions (CFMX Enterprise and Bluedragon JX/J2EE) include .JSP files, so we're on the way there I guess :-)

Example below.

Code for my include.jsp file

<%-- TEST STUFF --%>
<%@ page import="java.text.*,java.util.Date" %>
<%

SimpleDateFormat formatter = new SimpleDateFormat ("dd/MM/yy");
Date currentTime_1 = new Date();
String dateString = formatter.format(currentTime_1);

// Parse the previous string back into a Date. ParsePosition pos = new ParsePosition(0);
Date currentTime_2 = formatter.parse(dateString, pos);
%>

<br><br>
The date is <%= dateString %>

<br><br>

This is some random path stuff
<%= request.getServletPath() %>
<%= request.getHeader("path_info") %>

And then i can just include as below

<cfset getpagecontext().include("include.jsp")>

Smart use for includes

Thought i'd blog this as it's a lesser known feature of cfml includes. I know this works back to CF 4.5.

Take the following

<!--- get my include --->
<cfinclude template="mytemplate.cfm">

All pretty standard stuff. Well the interesting thing is that even if you change the file extension it will still parse the file and run any coldfusion code in there it finds.

So if we have a file

myinclude.inc

With the content

<cfoutput>#now()#</cfoutput>

then the code will still be run.

Where this is really useful is to create a Word document. To try this create a word document put in images tables etc etc. Then in your word document type in

<cfoutput>#now()#</cfoutput>
straight in the word doc then wrap the whole lot in say bold. Save the document as myinclude.rtf then try including it.

e.g.

e.g.

<cfheader name="content-disposition" value="attachment; filename=mydynamicdoc.doc"><cfcontent type="application/Word"><cfinclude template="myinclude.rtf">

Powered by BlogCFC created by Raymond Camden. Code Tweaks by Pixl8, Turbo charged by Blue Dragon.Net Version 7