13 Replies Latest reply on Feb 4, 2014 7:13 AM by Aegis Kleais

    Is it just me or are this.mappings acting funny?

    Aegis Kleais Level 3

      Let me preface this: The following code is in the pseudo-constructor of my application.cfc (outside all functions) and this is the FIRST run of the application (so the application has not yet initialized)

       

      With that being said, I wrote the following code:

       

      <cfset this.mappings[ '/model' ] = expandPath( '/path/to/models/folder' ) />

       

      To make sure it took, I dump it:

       

      <cfdump var="#directoryExists( '/model' )#" />

       

      And sure enough I get: YES.

       

      Remove the dump and add the following code:

       

      <cfset myConfig = new model.utils.Config() />

       

      And CF errors out telling me it cannot find a Config.cfc.  Well, I verified.  In that 'models' folder, there is a 'utils' folder and a 'Config.cfc' in there.  If I instead change the line to read:

       

      <cfset myConfig = new path.to.models.folder.utils.Config() />

       

      Then it works fine.  So in essence, the mapping is not working.  I have an odd feeling that this is all due to the fact that I'm doing this in the pseudo constructor area, but if that's the natural place where you define this-scoped variables, I would think this is OK.  I know the application.cfc is LIKE a CFC, but in some ways different.

       

      Well, if I create a this-scoped variable in some other CFC file, I can immediately reference the variable and value on the life after, even in that CFC's pseudo or in the INIT before I perform a <cfreturn this /> 

       

      I'm trying to understand why the mapping is not working.  A problem I have is that the returntype attribute of my Config.cfc is 'model.utils.Config', and this errors out when I use the 'new path.to.models.folder.utils.Config()' method, understandably because they're different FQDNs.

        • 1. Re: Is it just me or are this.mappings acting funny?
          Carl Von Stetten Adobe Community Professional & MVP

          I think I've seen others express problems with trying to use a mapping elsewhere within the pseudo-constructor, so you might want to try avoiding that.

           

          I'm guessing this is related to a previous thread on this forum where you talked more about your myConfig process.  I had done something similar in Application.cfc myself (albeit without a CFC file).  I read in an XML config file in the pseudo-constructor, parsed it, and inserted the "this" variables.  I then read the same XML file again in the onApplicationStart method and parsed out the "application" scope settings and inserted them.  Eventually I moved all the "this" stuff out of the XML file and hardcoded it in the Application.cfc file.  Why did I do this?  Because the pseudo-constructor is run on every request.  So on every request, my application was opening and parsing the XML file and rewriting the "this" scope, all of which added unnecessary overhead to my application.

           

          HTH,

          -Carl V.

          • 2. Re: Is it just me or are this.mappings acting funny?
            Aegis Kleais Level 3

            *** UPDATE ***

             

            Well, one of those funny things happened.  I came to realize that my understanding of expandPath() is wrong.  After having used it in a manner that was not as the function intended (but the result worked), I have now realized that this fluke needs to be resolved to a point where I can understand how expandPath(), directory/fileExists() and CFC dot notation works alongside CF mapping.

             

            I've been at this problem for about 4 hours now and nothing has made any sense.  The documentation provided by Adobe raises more and more questions and all the local testing I've been doing (where I'm ADAMANT a file exists and am being told it does not, and when I do something that should not exist, I'm being told I pathed to it properly).

             

            In these situations, it's always best to leave the problem alone and hit it again tomorrow from a fresh perspective, so I'm admitting a defeat with an asterisk for the time being, but I'll get at this again tomorrow.

            • 3. Re: Is it just me or are this.mappings acting funny?
              Aegis Kleais Level 3

              @Carl-

               

              I guess in the desire to build an automated application (cause let's be honest, how cool is it when you have a config file that controls how the application inits, am I right?), it seems you are where I might be heading.  I just didn't want to have to resort to static simplicity due to the fact that I couldn't comprehend a built-in function or how ColdFusion's mapping worked.

               

              I did consider the performance hit from doing the XML parsing every route.  In my application, after the initial heavy load of the startup, on each request, the pseudo runs a:

               

              Config.processAppPseudo()

               

              This iterates over a private structure variable in the object that contains all the key/value pairs (previously pulled from XML) and simply executes a <cfset structInsert( this, keyName, keyValue, true ) /> in a loop.  It's overhead, but an acceptable level I feel.  And if need be, I could have part of the startup BUILD a file dynamically created that has all the this-scope declarations.  To me, I just wanted any automated solution that did not resort in me hard-coding the variables.

              • 4. Re: Is it just me or are this.mappings acting funny?
                Aegis Kleais Level 3

                <cfdump var="#fileExists( expandPath( '/path/to/models/utils/Config.cfc' ) )#" /> <!--- This dumps YES. --->

                 

                <cfset this.mappings[ '/model' ] = expandPath( '/path/to/models/' ) /> <!--- Same as c:\web-root\path\to\models\ --->

                 

                <cfdump var="#fileExists( expandPath( '/model/utils/Config.cfc' ) )#" /> <!--- This dumps NO. I've yet to figure out why. --->

                 

                CF documentation states that fileExists() should work with in-memory addresses, but I don't know if that means 'mappings'.

                • 5. Re: Is it just me or are this.mappings acting funny?
                  Carl Von Stetten Adobe Community Professional & MVP

                  I could be wrong, but I don't think fileExists() works with mappings.  It'll work with relative paths, or with paths stored in variables, but not mappings.  AFAIK, use of mappings is limited to object creation methods (new, createObject, cfinvoke, etc.).

                   

                  I really wonder if you wouldn't be better off leveraging an existing framework (like FW/1) for much of what you have been working on lately.  For example, I know FW/1 has support for environment control (https://github.com/framework-one/fw1/wiki/Developing-Applications-Manual#wiki-environment- control) right out of the box.  This is the direction I will be moving toward in the next iteration of my applications.

                   

                  -Carl V.

                  • 6. Re: Is it just me or are this.mappings acting funny?
                    Aegis Kleais Level 3

                    I applaud Sean and his "Convention over Configuration" approach on FW/1.  And I know that FW/1 has been touted as a very simple and straight forward Framework.  There was a time a while back that I tried to learn it, found the documentation a bit lacking, and was told by its immediate community to "RTFM".  Problem was TFM wasn't making any sense to me.  When a manual does not talk in the lowest common denominator and assumes the reader has certain understandings that they currently don't, it makes for an even more frustrating experience.

                     

                    But here's the thing.  I do know that "reinventing the wheel" is not the most time-effective approach.  I will admit there is something in me that is uncomfortable with using other frameworks simply on the merits that I feel it will not allow me to be as customizable in my solutions as a home-grown one.  Also, I will state that in my own attempt to make my own framework (which, to be honest with you, has been going very well), I have learned SO. FREAKING. MUCH.  Sure, I didn't learn it in the most optimal way, many times I had to back track and "refactor" code when my envisioning of the framework became more and more clear; but wow, it's one heck of a ride and a sense of accomplishment when you can get through those milestones (mostly under my own steam, but definitely not completely without the help of others like yourself who have been very helpful).

                     

                    I keep repeating my mantra.  "A simple as possible, as complex as necessary."

                     

                    There is a nagging voice in my head that says "These other developers don't reinvent the wheel.  You're wasting time by learning frameworks this way.  When employers want to hire, they're not going to ask if you have experience in an unpopular framework."  (good ol, self doubt, eh?)  But I think for my current situation, I'm not going to say "No" to other frameworks, I just feel I have to currently power through this custom one.

                     

                    Besides, whether I use FW/1 or my own FW, my current issue is moreso about not understanding how I previously thought CF functioned.  That's something that needs to be understood despite my FW of choice.

                    • 7. Re: Is it just me or are this.mappings acting funny?
                      Carl Von Stetten Adobe Community Professional & MVP

                      Fair points.  Learning is always good.

                       

                      -Carl V.

                      • 8. Re: Is it just me or are this.mappings acting funny?
                        Aegis Kleais Level 3

                        Some just told me "Telling isn't Teaching", and I couldn't agree more.  Lecture has it's place but it's not an interactive experince with the student.  For me, I learn best when I am actively engaged with my teacher.  Sadly, and maybe this is just me, but it seems that this career does not lend itself to situations where you can get well-structured and interactive training on the wide variety of web development topics.  Instead, the self-taught skill of "Go out and find it yourself" is what's left in our bag of tricks; it does the job, but has a heavy cost associated with it.

                         

                        Not to mention, if all goes well, I'll be moving out to the Washington State area, which is a technical mecca (a 'techa', if you will), and I think I'll be exposed to more productive environments where I can really see my skills take off.  Let's just say my current environment.... well... if there was an ominous drum being beat at a steady rate, I'd say that it would fit in perfectly with the ambiance of technical savvy here.

                        • 9. Re: Is it just me or are this.mappings acting funny?
                          Aegis Kleais Level 3

                          Mappings cannot be referenced within the pseudo-constructor.

                           

                          That is the ONLY solution I have come to. They simply. do. not. work. in the pseudo-constructor.

                           

                          The moment I moved my line <cfset test = nameOfMapping.path.to.CFC() /> into the onApplicationStart() and out of the pseudo-constructor, BOOM, it found the file.

                           

                          I may not know WHY it functions in this way, as the moment CF processes a mapping, I feel it should be readily available to be used from that point afterwards, but this simply isn't the case.  I have spent hours on this problem trying every path combination possible, and only did I put my first attempt's syntax into the first BIF to fire off (onApplicationStart()), did CF finally respect the creation of the mapping and allow me to use it with the 'new' operator.

                           

                          @Carl

                           

                          This may have been why you chose to ultimately go with hard-coding those this-scoped variables for simplicity sake.  I can easily see why.  I think what I'll do before I try that is just use the non-mapped FQDN path for the first-run instantiation.

                          • 10. Re: Is it just me or are this.mappings acting funny?
                            Carl Von Stetten Adobe Community Professional & MVP

                            I'm only speculating here, but there must be some kind of chicken-or-egg thing going on here.  Maybe the "this" scope can't be read until the Application.cfc object is actually instantiated (which wouldn't actually be until after the pseudo-constructor has completed).

                             

                            I guess one could test this theory - define a custom "this" variable in Application.cfc (like this.myCustomVariable).  Then try to use it in another variable within the pseudo-constructor (like <cfset variables.myCustomVariable = this.myCustomVariable).  See if that works.

                             

                            Then try the same thing in a custom object (like myCustomObject.cfc).  See if that works.

                             

                            I may try this myself later as I don't have time right now.  But my suspicion is that both will behave the same - access to "this" scope variables cannot be done inside pseudo-constructor because the object is in the creation process and the "this" scope doesn't actually exist yet.

                             

                            -Carl V.

                            • 11. Re: Is it just me or are this.mappings acting funny?
                              Aegis Kleais Level 3

                              That's feasible, Carl.

                               

                              It's the inaugural run of the application, and the application.cfc's methods are only automatically called AFTER the file's pseudo-constructor runs.  And even though 1 line tells CF to make a per-application mapping to a valid path, CF won't internally initialize that mapping until the application has been created (ie, we've entered the onApplicationStart() method).  As a logical flow, this makes sense; but as a procedural, it does not.  Still, I think you might be on to something.

                               

                              During the first run, this-scoped variables can speak to one another BUT I did abort processing before CF goto consider the application.cfc "executed"; I have seen the behavior of CF change when you abort out at certain points.

                              • 12. Re: Is it just me or are this.mappings acting funny?
                                BKBK Adobe Community Professional & MVP

                                Aegis Kleais wrote:

                                 

                                <cfdump var="#fileExists( expandPath( '/path/to/models/utils/Config.cfc' ) )#" /> <!--- This dumps YES. --->

                                 

                                <cfset this.mappings[ '/model' ] = expandPath( '/path/to/models/' ) /> <!--- Same as c:\web-root\path\to\models\ --->

                                 

                                <cfdump var="#fileExists( expandPath( '/model/utils/Config.cfc' ) )#" /> <!--- This dumps NO. I've yet to figure out why. --->

                                 

                                CF documentation states that fileExists() should work with in-memory addresses, but I don't know if that means 'mappings'.

                                I think the second fileExists() call fails because ColdFusion interpretes the argument in expandPath as literally a relative path. Hence, assuming the current directory is c:\web-root,

                                 

                                expandPath( '/path/to/models/utils/Config.cfc' ) has the value c:\web-root\path\to\models\utils\Config.cfc

                                 

                                and

                                 

                                expandPath( '/model/utils/Config.cfc' ) has the value c:\web-root\model\utils\Config.cfc

                                • 13. Re: Is it just me or are this.mappings acting funny?
                                  Aegis Kleais Level 3

                                  Yeah, it seems that's the limitation of using fileExists() at that point in tandem with expandPath().  However my testing seems to prove that when it comes to mappings, they simply don't seem to be procedurally created in sequence.  If line 1 has the mapping definition, line 2 cannot use that mapping where CF would normally allow mappings on subsequent calls.  Seems like the pseudo-constructor allows you to define the mappings, but not utilize them until you're executing BIF's in the Application.cfc.