8 Replies Latest reply on Feb 19, 2007 9:29 AM by Newsgroup_User

    This scope: was use is it?

    dichi66 Level 1
      I don't get the "this" scope and the many examples given its use. Maybe I'm using it incorrectly, but it appears that a variable in this scope (at the top of a CFCOMPONENT) is set upon each invocation of a component. What use is it to simply overwrite the variable every time? If anything, there seems to be a performance penalty.

      In the Components section of the developers guide there is the implication that "this" variables are comparable to instance variables in a class. However, they are overwritten each time an instance is invoked.

      The "variables" scope seem to act more like proper instance variables, but they are private. So one would have to write accessors (get/set) for each.

      The bottom line is that "this" is not properly described in the documentation.
        • 1. Re: This scope: was use is it?
          Level 7
          However, they are overwritten each time an instance is invoked.

          Isn't that true in most OOP languages? I don't know much of this world,
          but it is my understanding that all variables are created when an object
          is initiated.

          But usually one only does this once, then the this scope lives until the
          object is destroyed.

          <cfset aVar = createObject("component","a.CFC.Path")>
          <cfset aVar.thisValue = "foobar">
          <cfoutput>#aVar.thisValue#</cfoutput>
          <cfset aVar.thisValue = "george">
          <cfoutput>#aVar.thisValue#</cfoutput>
          <cfset aVar = "">
          • 2. Re: This scope: was use is it?
            Dan Bracuk Level 5
            In general, scoping your variables will speed up your applications because cf doesn't have to try to figure it out.

            In a cfc, the this scope makes variables available to all the methods in that cfc. What you say about them being overwritten each time a cfc is invoked is true. However, if you create an object first, and call the methods individually, the variables will persist on each function call.

            The variables scope will work the same, at least to the extent that I understand it. They are available to every function if you instantiate them outside a function. They are private only if you do so inside a function. There is a time and a place for each.
            • 3. Re: This scope: was use is it?
              Level 7
              > it appears that a variable in this scope (at the
              > top of a CFCOMPONENT) is set upon each invocation of a component.

              Correct.


              > What use is
              > it to simply overwrite the variable every time?

              Restate your question in regards to a normal CFM template. I presume it
              doesn't seem strange to you that variables set on a CFM template get
              "overwritten" each time that the template is executed. Why would you
              expect differently of a CFC instance?

              The problem here is your use of the word "overwritten". Nothing gets
              "overwritten" because each instance of a CFC is a separate object. It's
              not the SAME object each time. The THIS-scoped variables in the
              pseudo-constructor of a CFC get *set* each time the CFC is instantiated.
              But it's a new variable; not an overwriting of an existing one.


              > In the Components section of the developers guide there is the implication
              > that "this" variables are comparable to instance variables in a class.

              I'd like to see the page reference for that.

              BTW: you don't have "instance variables of a class", you can only have
              "instance variables of an OBJECT".


              > However, they are overwritten each time an instance is invoked.

              You don't invoke an *instance*. You invoke a CFC, and it *creates* an
              instance (of that CFC). Thereafter you call methods of the instance. Or
              if you set THIS-scoped variables (which is generally considered poor
              practice anyhow), access its public variables.


              > The "variables" scope seem to act more like proper instance variables, but
              > they are private. So one would have to write accessors (get/set) for each.

              Yes the VARIABLES scope is like *protected* instance variables (not
              private ones: there is no "private" variables space in CF). And
              THIS-scoped variables are *public* instance variables.


              > The bottom line is that "this" is not properly described in the documentation.

              Well there's this:
              http://livedocs.adobe.com/coldfusion/7/htmldocs/00000912.htm

              And this:
              http://livedocs.adobe.com/coldfusion/7/htmldocs/00001054.htm

              I'm not sure what more you'd be expecting. There's not much to the
              concept, and that pretty much covers it.

              --
              Adam
              • 4. Re: This scope: was use is it?
                Level 7
                > The variables scope will work the same, at least to the extent that I
                > understand it. They are available to every function if you instantiate them
                > outside a function. They are private only if you do so inside a function.
                > There is a time and a place for each.

                That's not quite it.

                THIS-scoped variables live for the duration of the CFC instance, are then
                available to all code within the CFC, as well as the calling code. The
                closest Java equivalent is a public member variable.

                VARIABLES-scoped variables live for the duration of the CFC instance, are
                then available to all code within the CFC, but NOT the calling code. The
                closest Java equivalent is a *protected* (NOT private) member variable.

                Function-local variables (as declared with the VAR keyword, and have no
                scope) are local to the method in which they are created,a nd only exist
                for the life of the method call. These are directky equivalent to the the
                same concept in Java.

                --
                Adam
                • 5. Re: This scope: was use is it?
                  dichi66 Level 1
                  Maybe I wasn't clear. Let me explain it through a typical way that I would use it (and expect it to work). In OOP I would create an object (instance of a class). I assume this is comparable to CFOBJECT. Then I would call methods on the object, which I assume would be comparable to CFINVOKE.

                  However, the THIS variables are reset on each CFINVOKE call to the same object (instance). In other words, the object doesn't retain its state between CFINVOKE calls. Each time I call the object (via CFINOKE) It is like the object gets reinitialized each time.

                  Doesn't seem useful to me.
                  • 6. Re: This scope: was use is it?
                    Level 7
                    However, the THIS variables are reset on each CFINVOKE call to the same
                    object (instance). In other words, the object doesn't retain its state
                    between CFINVOKE calls. Each time I call the object (via CFINOKE) It is
                    like the object gets reinitialized each time.

                    Doesn't seem useful to me.


                    Sounds like you are using <cfinvoke...> incorrectly for what you want to
                    do. <cfinvoke...> can also be used it create an instance of the object
                    similar to <cfobject...> In fact there are at least three ways you can
                    create objects in CF, <cfobject...>, <cfinvoke...> and createObject().

                    If you just want to call methods with the <cfinvoke...> tag, do not pass
                    it the name of your class (cfc), pass it the variable that you created
                    an instance of the class with the <cfobject...> tag.

                    But you don't have to use <cfinvoke...> you can just call the methods
                    directly off of the object variable. But the <cfinvoke...> tag does
                    make some tasks a touch easier or more self documented if you have
                    complex arguments.

                    <!--- This form of <cfinvoke...> creates an instance of myClass and
                    calls a method on it, returns the value and then discards the instance. --->
                    <cfinvoke component="myClass.cfc" method="whatever" anArg="something"
                    returnvariable="done">


                    <!--- This form of <cfinvoke...> uses an instance of myClass that was
                    previous created in some manner and stored in the myOjbectVar variable,
                    could be a previous <cfinvoke...> or <cfobject...> tag or a
                    createObject() function. --->
                    <cfinvoke component="#myObjectVar#" method="whatever" anArg="something"
                    returnvariable="done">

                    <!--- These will accomplish the same functionality as the previous
                    <cfinvoke example. --->
                    <cfset done = myObjectVar.whatever("something")>
                    <cfset done = myObjectVar.whatever(anArg:"something")>


                    In these latter forms, your internal variables would persist as long as
                    the object variable persists.
                    • 7. Re: This scope: was use is it?
                      Dan Bracuk Level 5
                      Your second assumption is incorrect.

                      If you create an instance of an object with either cfobject or createfobject, you would not use cfinvoke to call the methods. You would call them using this sort of syntax.

                      SomeVariable = ObjectName.MethodName(arguments);

                      This technique is useful if you are going to access more than one method.

                      What cfinvoke enables you to do is to invoke a component's method without instantiating an object first. This technique is useful if you are going to access only one method.
                      • 8. Re: This scope: was use is it?
                        Level 7
                        > What cfinvoke enables you to do is to invoke a component's method without
                        > instantiating an object first. This technique is useful if you are going to
                        > access only one method.

                        That's not entirely true. You CAN use <cfinvoke> to create an object as
                        well. And you CAN use <cfinvoke> to call methods on an already-existing
                        object.

                        I think the OP is doing the former when they ought to be doing the latter.

                        And... here's the relevant docs...
                        http://livedocs.adobe.com/coldfusion/7/htmldocs/00000281.htm

                        (see Syntax 1 and Syntax 4a)

                        --
                        Adam