Monday, November 05, 2007

onMIssingMethod question

I've just started experimenting with the onMissingMethod capability in cf8. It looks like the function only fires when missing methods are fired from outside the component. If you attempt to call a missing method from inside, you get a message stating that your method is undefined as a variable.

This is unfortunate because it precludes me from using it as a way to replace my getter/setter functions since I use them to enforce my business rules in a roundabout way. My setters get called in my init() method to set up the object's properties. Doing this instead of just setting the property value lets me enforce any constraints on my data on the way in to the object. It looks like I can't actually use the onMissingMethod capability for a missing setter. Is this true? Is there a workaround?

5 comments:

  1. I'd bet that Sean Corfield can answer that. He's a huge proponent of onMissingMethod, and for exactly what you're talking about.

    However, here's my $0.02: Instead of using the internal getters and setters, why not just do your CFSET statements directly in the init function? You can't be getting too far abstracted if the variables are defined as parameters for init...

    ReplyDelete
  2. If your onMissingMethod examines the args and then just chains to code to set a variable, you could make _that_ code abstract, ie, a generic set(). In your init, instead of doing setX(...), just call the generic set. So your init would call the right method - and your onMissingMethod would also call set().

    ReplyDelete
  3. @TuttleTree - My setters tend to look a little different than most cf setters I've run across. Instead of assigning the property value, I use it as a simple wrapper to run a "test" method and a "do" method. The test method generally contains all of my business logic which can be pretty involved. It does things like regular expression validation of and enforcement of some collaboration rules. I expect to have to write my test functions pretty much by hand all the time. If something doesn't pass, I throw a descriptive error. As for the "do" method, it's a simple method that actually assigns the value to the property. It's very simple and a good candidate for onMissingMethod as well. I have it split from the validation function for two reasons. First, it allows me to bypass my business rules while I'm working if necessary and second, I like the way it allows me a different vector to the property during unit testing. That's why I would like to use my setters from init(). It doesn't necessarily mean it has to stay that way, it's just how I have things set up now.

    @Raymond - I'm not sure if your approach would solve my issues, but it's certainly worth looking at a little closer.

    My primary interest in looking at this was to reduce a little clutter, but it would make my code no longer work on cf6 and 7. I'm thinking maybe I just live with it the way it is for now.

    ReplyDelete
  4. Try this.getFoo() and this.setFoo(x) instead of just getFoo() and setFoo(x).

    ReplyDelete
  5. @seancorfield - Thanks! That was just enough of a hint to persue this a bit more. After a bit of wrestling, using "this" did the trick. I still have a bit of work to do to make the code a little safer, I think it's pretty promising.

    The way I have it wired up, you can't call get or set on a property unless the actual property declaration is included, which I like. It makes my properties show up in the services browser even better than they did with all of the methods actually built. Now, I just see "myProperty" as a property and the rest of the methods are actually things that I want to write code for. So far this seems pretty great.

    ReplyDelete