The init method is inherited from collection into usercollection;
variables are inherited as well, are they not? Why should I avoid
reusing the parent class's variables in the child class? In my template,
I call the init, and pass in its argument. The var keyword won't do
because the _data and _DSN variables should hold a data cache for the
life of the application. 

Perhaps my impression of inheritance is wrong: I'm trying to use it to
map objects together as they are related, and for responsible code
reuse, not just to reference another object's methods easily.

Just for kicks, by the way, I took the code and smashed it all back into
the usercollection cfc; it also threw the error. Ahhh hell, I'm going to
quit coding and get a job as a line cook or something.

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Ryan Duckworth
Sent: Tuesday, July 06, 2004 5:06 PM
To: [EMAIL PROTECTED]
Subject: RE: [CFCDev] Simple, stupid inheritance/scope issue.



You need a super.init() inside of the pseudo-constructor area of your
"usercollection" CFC.
e.g. between the <cfcomponent> and your first <cffunction> tag.
Without this, the _data variable will never get created, whether you
extend it or not.

Personally, I use the "var" scope to avoid this type of problem.  If you
don't use var you 
will create more problems than you will solve.  The extends is to
reference the super's functions easily.
I would try to avoid touching it's variables, and if you do, use getter
and setter functions.

Hope this helps.  

Ryan Duckworth
Macromedia ColdFusion Certified Professional
Uhlig Communications
10983 Granada Lane 
Overland Park, KS 66207 
(913) 754-4272


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Davis, Eric
Sent: Tuesday, July 06, 2004 3:26 PM
To: [EMAIL PROTECTED]
Subject: RE: [CFCDev] Simple, stupid inheritance/scope issue.


Okay, since the mock code might not have the same issue, here's the
actual stuff.

<cfcomponent displayname="Collection" hint="A base collection object">
  <cfset _DSN = "" />
  <cfset _data = "" />
  <cffunction name="init" hint="Initialize the collection:
pseudo-constructor" returntype="collection" output="no">
    <cfargument name="datasource" required="Yes" type="string" />
    <cfset _DSN = arguments.datasource />
    <cfset _data = "" />
    <cfreturn this />
  </cffunction>
  <cffunction name="read" hint="Obtain collection data from database"
returntype="query" output="no">
    <cfif IsSimpleValue(_data)>
      <cfset refresh() />
    </cfif>
    <cfreturn _data />
  </cffunction>
  <cffunction name="refresh" hint="Force re-obtain collection data from
database" returntype="collection" output="no">
    <cfthrow type="interface.methodNotInherited" message="The refresh
method of the collection class must be overridden by its inheriting
classes" />
  </cffunction>
  <cffunction name="deleteRecord" hint="Obtain collection data from
database" returntype="collection" output="no">
    <cfargument type="string" name="recordID" required="yes" />
    <cfthrow type="interface.methodNotInherited" message="The read
method of the collection class must be overridden by its inheriting
classes" />
  </cffunction>
</cfcomponent>

<cfcomponent displayname="User Collection" extends="collection" hint="A
collection of users">
  <cffunction name="refresh" hint="Force re-obtain collection data from
database" returntype="collection" output="no">
    <cfquery name="_data" datasource="#_DSN#">
      SELECT  *
      FROM  users
    </cfquery>
    <cfreturn this />
  </cffunction>
  <cffunction name="deleteRecord" hint="Obtain collection data from
database" returntype="collection" output="no">
    <cfargument type="string" name="recordID" required="yes" />
    <cfset var deleting = "" />
    <cfquery name="deleting" datasource="#_DSN#">
      DELETE
      FROM  users
      WHERE  user_id = #arguments.recordID#
    </cfquery>
    <cfreturn refresh() />
  </cffunction>
</cfcomponent>

Framework templates:
(name-locked write if not defined)
<cfset application.collections.users =
CreateObject("component","usercollection").init(application.DSN.safeTrac
k) />
...
<cfset StructAppend(request, duplicate(application)) />

Calling template:
<cfdump var="#request.collections.users.read()#" />

Error:
Variable _data is undefined.
The error occurred in collection.cfc: line 11


Dave, thanks for taking a look at this earlier. Hopefully somebody will
help me find what I'm missing.

-----Original Message-----
From: Davis, Eric

Sadly, that was almost exactly what I had before I pulled it into the
pseudo-constructor, and it still threw the same error.

<cfcomponent displayname="base">
  <cffunction name="init">
    <cfset _hidden = "" />
    <cfreturn this />
  </cffunction>
  <!--- read function --->
</cfcomponent>

<!--- child cfc exactly the same --->

<!--- calling template --->
<set obj = createObject("component", "child").init() />
<dump var="#obj.read()#" />

BZZZT - same error.

-----Original Message-----
From: David Ross

I'm guessing the pseudo-constructor area is not run for the base
component. Put that code in a function (call it init(), please), then
call super.init() upon instantiating the child component.


>>> [EMAIL PROTECTED] 7/6/2004 2:23:09 PM >>>
I'm sure I'll kick myself shortly, but after spending two weeks trying
and failing to write a cross-browser javascript webservice consumption
class and then a week on vacation in Mexico, apparently my simple CFC
skills have left me entirely. This problem has to do with the
inheritance chain and the unnamed scope. Here's a mockup of the code
I've got.

<-- base.cfc --->
<cfcomponent>
   <cfset _hidden = "" />
   <cffunction name="read" returntype="struct">
      <cfif IsSimpleValue(_hidden)>
         <cfset setValue() />
      </cfif>
      <cfreturn _hidden />
   </cffunction>
</cfcomponent>

<-- child.cfc -->
<cfcomponent extends="base">
   <cffunction name="setValue" returntype="base">
      <cfset _hidden = StructNew() />
      <cfset _hidden.key1 = "value1" />
      <cfreturn this />
   </cffunction>
</cfcomponent>

When I invoke child.cfc and try the read() method, I get an error that
says _hidden is not defined, thrown in the IsSimpleValue() check.

Why? I've defined no arguments so that collision isn't possible, and I'm
just trying to use the unnamed scope - note that in a prior version of
similar functionality, when all of this is in one cfc, there's no error
whatsoever. 

Other components I've written use an "instance" structure in the unnamed
scope, and work just fine. What could possibly be wrong with this code?
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at
www.mail-archive.com/[EMAIL PROTECTED]


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at
www.mail-archive.com/[EMAIL PROTECTED]
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]

Reply via email to