On 4/4/07 12:05 PM, Ovid wrote:
> Note the 'return' condition.  I found that if I didn't have that in,
> the following would throw an exception:
> 
>   my $os = Donhost::OS->new( os => 'ubuntu' );
> 
> The hack guarantees that only things like the following throwing
> exceptions:
> 
>   $os->os('windows');
>   $os->description('sucks');
> 
> The hack relies on the order of call stack frames being different when
> I'm constructing an object or just setting an accessor directly.  How
> can I do this without relying on the internals like this?

The problem is that this:

    $o = Foo->new(a => 123)

is really this:

    $o = Foo->new;
    $o->a(123);

The only way to distinguish the two is by calling context.  That said, there
are (slightly) better ways to detect the context than using caller().
Here's what I suggest:

    # Override init in you common base class
    # (See the Rose::Object docs for details)
    sub init
    {
      my($self) = shift;
      local $self->{'__allow_set'} = 1; # or whatever attr name you pick
      $self->SUPER::init(@_);
    }

Then, in your trigger, replace this:

    my ($called_from) = caller(1);
    return if $called_from eq 'Rose::Object';

with this:

    return if shift->{'__allow_set'};

Granted, this is still a bit of a hack, but at least it only relies on
public APIs, rather than internal implementation details.

-John
    

    



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to