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