• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Using CFC's

Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Hello,

I have a simple CFC defined as such. And named ct.cfc

<cfcomponent>
    <!--- Celsius to Fahrenheit conversion method. --->
    <cffunction name="ctof" output="false">
        <cfargument name="temp" required="yes" type="numeric">
        <cfreturn ((temp*9)/5)+32>
    </cffunction>
</cfcomponent>

Then I have a .cfm file named test.cfm and both the cfc file and the cfm file are in the same directory. The test.cfm file is below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
</head>
<body>
<cfscript>
  obj1 = createObject("component","ct");
  obj1.ctof(temp=100);
</cfscript>

</body>
</html>

I can't seem to figure out how to print the output of obj1 to the screen. I have tried obj1.temp and that does not work. Also all of the code above does not throw an error. It is only when I try to cfoutput the value I run into problems. So how do you print the value? It should be 212.

Thanks,

Jim

TOPICS
Advanced techniques

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Jun 06, 2011 Jun 06, 2011
Use this as an example.

<cfset x=5>

then 200 lines later I say:

<cfoutput>#x#</cfoutput>

Right, so how about:

<cfset x = obj1.ctof(temp=100) >

then 200 lines later I say:

<cfoutput>#x#</cfoutput>


Is that what you're trying to do? That'll set the variable "x" to be a copy of the value returned from your CFC's method. You can then repeatedly use said variable without actually running the method again.

Votes

Translate

Translate
Guide ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

You're within a CFSCRIPT block, so you cannot use CFOUTPUT; you need the script version - writeOutput() - instead.

writeOutput(obj1.ctof(temp=100)) ;

Will put the return variable out to the screen.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Owain thanks for the answer. I should have been more specific. What I want to do is say output the variable later I know obj1 in some way has the value 212.

So what I want to do is get 212 to the screen. I do not want to output the variable as I define it.  Use this as an example.

<cfset x=5>

then 200 lines later I say:

<cfoutput>#x#</cfoutput>

Thanks,

Jim

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Use this as an example.

<cfset x=5>

then 200 lines later I say:

<cfoutput>#x#</cfoutput>

Right, so how about:

<cfset x = obj1.ctof(temp=100) >

then 200 lines later I say:

<cfoutput>#x#</cfoutput>


Is that what you're trying to do? That'll set the variable "x" to be a copy of the value returned from your CFC's method. You can then repeatedly use said variable without actually running the method again.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Owain thanks!

I was trying to learn about objects in CF, was my goal. I am guessing now there is now way

to refer to obj1 to get at the 212. Meaning unless you set, as you did with <cfset x = obj1.ctof(temp=100) >

there is no other way to get at the 212. I was trying with obj1.temp and obj1 but to no avail.

Thanks,

Jim

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

You *could* make it so obj1.temp became set with the last value of the function, but it would be nonsensical and confusing.

When you call a method, it returns something (unless it is set to return void). You then have three choices what to do with it:

1) Ignore it. It's not the return variable that means anything, it's what the function does that's important.

  <cfset obj1.sendMeAnEmail() />

2) Output/use it then and there

  <cfoutput>#obj1.returnSomeNumber()#</cfoutput>

  or

  <cfif obj1.returnNumber() GT 100 >

    do something

  <cfelse>

    do something else

  </cfif>

3) Store it for later use

  <cfset MyReturnValue = obj1.doSomething() />

As Mike suggested, have a read through some tutorials to make sure you have a really firm understanding of all the basics before trying to dive too deep into object-oriented programming.

O.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Owain thanks again on the follow up. I guess in laymans terms I was thinking somehow obj1 contained some things(like 212) since I created it. Another words I can go back later to that instance and get the temp. Either way I will study this (CFC) area more.

Jim

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Not the way you wrote your CFC (aka object).

You sound like you are looking for the ColdFusion version of "Public" object variables.

You CAN do that in a CFC using the "THIS" scope.

<cfcomponent> 
    <!--- Celsius to Fahrenheit conversion method. --->
    <cffunction name="ctof" output="false">
        <cfargument name="temp" required="yes" type="numeric">
        <cfset this.f = ((temp*9)/5)+32>
    </cffunction>
</cfcomponent>

You COULD then do this in your code.

<cfoutput>#obj1.f#</cfoutput>

BUT MOST experienced developers would probably advise that your first code sample was a better practice.

Public variables can be very problematic in good OOD practices, albeit for such a simple example is this it is hard to see.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 07, 2011 Jun 07, 2011

Copy link to clipboard

Copied

Hello iIssac,

That is what I was trying to do, or what I expected would happen. And like you said not the best way to write OO code.

So overall it would be as follows:

<!--- CFC file named ff.cfc --->

<cfcomponent>
    <!--- Celsius to Fahrenheit conversion method. --->
    <cffunction name="ctof" output="false">
        <cfargument name="temp" required="yes" type="numeric">
        <cfset this.f = ((temp*9)/5)+32>
    </cffunction>
</cfcomponent>

<!--- End of CFC file --->

<!--- Snippet from a CFM  file --->

<cfset s= New ff()>   <---- Here is a new instance of the ff object being created named s.
<cfset s.ctof(temp=35)>  <----- Here is where I use the ctof method to convert from Celsius to Farenheit.
<cfoutput>#s.f#</cfoutput>  <---- Here is where I output the Farenheit temp that is associated with the s instance of the ff object.

<!---  End of snippet from CFM file --->

Thanks,

Jim

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Jun 07, 2011 Jun 07, 2011

Copy link to clipboard

Copied

Jim

That's exactly correct, and would work how you say. However I would *strongly* urge you to just forget about the fact that even works, as it goes against pretty much every programming rule going.

It also only really works because ColdFusion is so forgiving, in a "proper" programming language you'd have to set up the property beforehand, set its datatype, it'd make no sense as that's not what properties are meant to be used for.

So yes it works, but I wouldn't get too carried away with it

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jun 07, 2011 Jun 07, 2011

Copy link to clipboard

Copied

As Owain said, your code will work as expected and most would advise you to never write code like that.

A more oo compliant example would be to use a getter with the setter you have created and use the private "Variables" scope.

<!--- CFC file named ff.cfc --->

<cfcomponent>
    <!--- Celsius to Fahrenheit conversion method. --->
    <cffunction name="ctof" output="false" return="void">
        <cfargument name="temp" required="yes" type="numeric">
        <cfset variables.f = ((temp*9)/5)+32>
    </cffunction>

     <cffunction name="getF" output="false" return="number">

          <cfreturn variables.f>

     </cffunction>
</cfcomponent>

<!--- End of CFC file --->

And then you just need a slight modification to your CFM example.

<!--- Snippet from a CFM  file --->

<cfset s= New ff()>   <---- Here is a new instance of the ff object being created named s.

     ...

<cfset s.ctof(temp=35)>  <----- Here is where I use the ctof method to convert from Celsius to Farenheit.

     ...

<cfoutput>#s.getF()#</cfoutput>  <---- Here is where I output the Farenheit temp that is associated with the s instance of the ff object.

<!---  End of snippet from CFM file --->


Creating a whole bunch of 'getter' and 'setter' functions for a large, complex object can get tedious.  So the latest CF version includes some ability to automatically have this functionality with Components.  See the documentation for the full details.  (I have not used it enough todate to comment on it yet)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 08, 2011 Jun 08, 2011

Copy link to clipboard

Copied

As Owain said, your code will work as expected and most would advise you to never write code like that.

A more oo compliant example would be to use a getter with the setter you have created and use the private "Variables" scope.

Irrespective of the merits of exposing variables to calling code via the THIS scope  - which I think is fine in the appropriate situation - it's not an appropriate approach in the given example.  A conversion function should return a result, not set something in the state of the CFC instance.

I could see how someone might have a Temperature.cfc, which one could init with a temperature like this:

(let's see if Jive will let me post angle-bracket stuff today...):

<!--- Temperature.cfc --->

<cfcomponent output="false" hint="Represents a temperature.  Exposes the temperature IN_CELSIUS and IN_FAHRENHEIT">

    <cfset THIS.IN_CELSIUS = 0>
    <cfset THIS.IN_FAHRENHEIT = 0>
   
    <cffunction name="init" returntype="Temperature" access="public" output="false" hint="Sets the temperature in celsius and fahrenheit.">
        <cfargument name="temperature" type="numeric" required="false">
        <cfargument name="scale" type="string" required="false" default="CELSIUS" hint="One of either CELSIUS or FAHRENHEIT.">
        <cfscript>
            if (arguments.scale == "FAHRENHEIT"){
                THIS.IN_FAHRENHEIT = arguments.temperature;
                THIS.IN_CELSIUS = ((arguments.temperature - 32) / 9) * 5);
            }else{
                THIS.IN_CELSIUS = arguments.temperature;
                THIS.IN_FAHRENHEIT = ((arguments.temperature / 5) * 9) + 32;
            }
            return this;
        </cfscript>
    </cffunction>

</cfcomponent>

And then call it like this:

<cfset boilingPointOfWaterAtSeaLevel = new Temperature(100)>
<cfoutput>
    For Americans, the temperature is #boilingPointOfWaterAtSeaLevel.IN_FAHRENHEIT#<br />
    For everyone else, the temperature is #boilingPointOfWaterAtSeaLevel.IN_CELSIUS#<br />
</cfoutput>

Why on earth one would want a temperature CFC like this, I dunno.  But it's an example of a reasonable use of THIS-scoped variable usage.  One could also implement this with getters and setters, but that often seems like code for the sake of code to me, especially if teh getter/setter is not actually performing any logic beyond setting or returning the variable.

The difference is that Temperature.cfc represents an object: it's a temperature.  In the OP's case, they've got a conversion function which is basically a UDF, and would be more at home in temperatureLib.cfm, or maybe TemperatureLib.cfc.  But it's a library function, not an object method (in the way they're using it).

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 08, 2011 Jun 08, 2011

Copy link to clipboard

Copied

LATEST

Hi Adam,

This entire post came about with this link:

http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7e03.html

Jim

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

you may want to review this https://github.com/mhenke/CFML-in-100-minutes

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 06, 2011 Jun 06, 2011

Copy link to clipboard

Copied

Mike thanks for the link looking now

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation