From: Vsevolod (S. I. <si...@cs...> - 2004-01-05 22:53:01
|
Chris, At the risk of being a pain, I'll repost my two previous questions about links_to: I have a current project which is stalled because of them. This refers to the solution that you suggested when I do this: SPOPS class: SPOPS_Books Your class: MyBooks isa SPOPS_Books SPOPS class: SPOPS_Publisher Your class: MyPublisher isa SPOPS_Publisher Then declare in your publisher configuration: links_to => { MyBooks => 'link_table' } 1. My classes have a superclass. Let's call it MyObject. So I inherit MyBooks from SPOPS_Books and MyObject. I have to double-dispatch the new() method, but I can live with it. However, I use strict field checking and field autodiscovery. When I begin to store attributes in MyObject via the regular Perl getter/setter methods which use $self as a hashref, I start to get SPOPS errors about accessing fields that are not present. Obviously, I can turn strict fields checking off, but I'd like to retain that. The alternative is to somehow keep autodiscovery, but add in the config hash of SPOPS_Books additional fields which correspond to "instance variables" of MyObject. I am not sure how to do it, but even if I could, it's messy because I'll have to repeat it in every SPOPS_* class. This can be made a little less messy if I do not inherit from MyObject, but store a reference to it, but this one reference still has to be mentioned in SPOPS config. 2. I am trying to use objects that refer to each other, and I use links_to in both configuration. (I call them Job and Task, but they are similar in their relationship to Publisher and Book). I attach the four class files and the script that tries to use them. I inherit Job from SPOPS_Job and Task from SPOPS_Task. The SPOPS configuration refers to Common.pm, which would be different in your case. There are four possible configurations: SPOPS_Job links to SPOPS_Task, SPOPS_Task links to SPOPS_Job SPOPS_Job links to Task, SPOPS_Task links to SPOPS_Job SPOPS_Job links to SPOPS_Task, SPOPS_Task links to Job SPOPS_Job links to Task, SPOPS_Task links to Job The first three work, but the last one, which is of greater interest, does not. Could you please look at this and tell me if I am doing anything wrong? The error message is: Cannot run behavior in [links_to] [SPOPS_Job]: Failed to retrieve configuration from Compilation failed in require at Job.pm line 5. The tables that the config files refer to are created thusly: CREATE TABLE `Job` (`job_id` int(11)); CREATE TABLE `Task` (`task_id` int(11)); CREATE TABLE `JobToTask` (`id` int(11), `job_id` int(11), `task_id` int(11)); Thanks, Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com America's business leaders simply don't want to think about complex technology issues - they want to think about golf. Microsoft promises them that. Andrew Grygus, www.aaxnet.com |
From: Chris W. <ch...@cw...> - 2004-01-06 00:53:56
|
On Jan 5, 2004, at 5:52 PM, Vsevolod (Simon) Ilyushchenko wrote: > At the risk of being a pain, I'll repost my two previous questions > about links_to: I have a current project which is stalled because of > them. Hope I'll be able to help. > This refers to the solution that you suggested when I do this: > > SPOPS class: SPOPS_Books > Your class: MyBooks isa SPOPS_Books > SPOPS class: SPOPS_Publisher > Your class: MyPublisher isa SPOPS_Publisher > > Then declare in your publisher configuration: > > links_to => { MyBooks => 'link_table' } Okay, I've got a test script + classes that has this setup with strict field checking and field autodiscovery. It all works ok with: Book isa Book_Persist Book linksto Publisher Publisher isa Publisher_Persist Publisher linksto Book Files are attached in book_sample.tar.gz > 1. My classes have a superclass. Let's call it MyObject. So I inherit > MyBooks from SPOPS_Books and MyObject. I have to double-dispatch the > new() method, but I can live with it. This might be a problem. How are you dispatching new()? > Obviously, I can turn strict fields checking off, but I'd like to > retain that. The alternative is to somehow keep autodiscovery, but add > in the config hash of SPOPS_Books additional fields which correspond > to "instance variables" of MyObject. I am not sure how to do it, but > even if I could, it's messy because I'll have to repeat it in every > SPOPS_* class. This can be made a little less messy if I do not > inherit from MyObject, but store a reference to it, but this one > reference still has to be mentioned in SPOPS config. As an aside: you can also use the kludge of storing it in a field named 'tmp_foo' -- anything that starts with 'tmp_' is ignored by the tie implementation. (Did I mention that I hate tie? :-) > 2. I am trying to use objects that refer to each other, and I use > links_to in both configuration. (I call them Job and Task, but they > are similar in their relationship to Publisher and Book). > > I attach the four class files and the script that tries to use them. > I inherit Job from SPOPS_Job and Task from SPOPS_Task. The SPOPS > configuration refers to Common.pm, which would be different in your > case. One thing I noticed is that you have a 'require SPOPS_Job' in Job and a corresponding one for Task. Get rid of that, you don't need it and might be causing the problem: > The error message is: > Cannot run behavior in [links_to] [SPOPS_Job]: Failed to retrieve > configuration from Compilation failed in require at Job.pm line 5. Let me know about the 'new()' dispatch and whether the sample works for you and if it's different than your setup in any way other than the common inherited class. (It uses SQLite like before) Chris -- Chris Winters Creating enterprise-capable snack systems since 1988 |
From: Vsevolod (S. I. <si...@cs...> - 2004-01-06 16:33:03
|
> > Okay, I've got a test script + classes that has this setup with strict > field checking and field autodiscovery. Sorry, no script was attached. :( > >> 1. My classes have a superclass. Let's call it MyObject. So I inherit >> MyBooks from SPOPS_Books and MyObject. I have to double-dispatch the >> new() method, but I can live with it. > > This might be a problem. How are you dispatching new()? Nothing fancy - in MyObject: sub new { my ($proto) = shift; my %args = %{$_[0]}; my $self = $proto->SUPER::new(@_); $self->_new(\%args); return $self; } MyObject inherits from ProtoObject, which is a parent also to non-SPOPS classes. In ProtoObject, _new() calls $self->new(), and everybody's happy. Since only one ugly method was introduced, this is not a big deal. > As an aside: you can also use the kludge of storing it in a field named > 'tmp_foo' -- anything that starts with 'tmp_' is ignored by the tie > implementation. (Did I mention that I hate tie? :-) Okay, I'll try to work with this. > One thing I noticed is that you have a 'require SPOPS_Job' in Job and a > corresponding one for Task. Get rid of that, you don't need it and might > be causing the problem: Thanks - that helped my script to compile! However, when I added another line: Job->fetch(1) I got this: Can't locate package SPOPS_Job for @Job::ISA at script.pl line 5. Can't locate package SPOPS_Job for @Job::ISA at script.pl line 6. Can't locate package SPOPS_Job for @Job::ISA at script.pl line 6. Can't locate object method "fetch" via package "Job" at script.pl line 6. Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com America's business leaders simply don't want to think about complex technology issues - they want to think about golf. Microsoft promises them that. Andrew Grygus, www.aaxnet.com |
From: Chris W. <ch...@cw...> - 2004-01-06 18:27:22
|
On Jan 6, 2004, at 11:32 AM, Vsevolod (Simon) Ilyushchenko wrote: >> Okay, I've got a test script + classes that has this setup with >> strict field checking and field autodiscovery. > > Sorry, no script was attached. :( Dratted mailing list managers! Try: http://www.cwinters.com/raw/book_sample.tar.gz >>> 1. My classes have a superclass. Let's call it MyObject. So I >>> inherit MyBooks from SPOPS_Books and MyObject. I have to >>> double-dispatch the new() method, but I can live with it. >> This might be a problem. How are you dispatching new()? > > Nothing fancy - in MyObject: > sub new > { > my ($proto) = shift; > my %args = %{$_[0]}; > > my $self = $proto->SUPER::new(@_); > $self->_new(\%args); > > return $self; > } > > MyObject inherits from ProtoObject, which is a parent also to > non-SPOPS classes. In ProtoObject, _new() calls $self->new(), and > everybody's happy. Since only one ugly method was introduced, this is > not a big deal. Ugh, that blows. I'm going to introduce a initialize_custom() method to SPOPS.pm which you can override to do whatever you want. This is a very useful feature and I can't believe it's not there already. > Thanks - that helped my script to compile! However, when I added > another line: > Job->fetch(1) > I got this: > > Can't locate package SPOPS_Job for @Job::ISA at script.pl line 5. > Can't locate package SPOPS_Job for @Job::ISA at script.pl line 6. > Can't locate package SPOPS_Job for @Job::ISA at script.pl line 6. > Can't locate object method "fetch" via package "Job" at script.pl line > 6. You still need to initialize your SPOPS classes before trying to use 'Job'. See the tarball above for my example. Chris -- Chris Winters Creating enterprise-capable snack systems since 1988 |
From: Chris W. <ch...@cw...> - 2004-01-07 01:38:02
|
On Jan 6, 2004, at 2:55 PM, Vsevolod (Simon) Ilyushchenko wrote: >> Ugh, that blows. I'm going to introduce a initialize_custom() method >> to SPOPS.pm which you can override to do whatever you want. This is a >> very useful feature and I can't believe it's not there already. > > Cool - should be useful. This is in CVS now -- if you're interested LMK and I'll make a dist available. >> You still need to initialize your SPOPS classes before trying to use >> 'Job'. See the tarball above for my example. > > OH!!! You are doing this OUTSIDE of the classes! Thanks, got it! > > But... this violates encapsuliation... though I see how you have to go > outside of the box to define the circular relationships... Yeah... what you're doing is defining an object and inheriting all the persistent behavior. Even though the class with the persistent behavior isn't defined until you create it using SPOPS::Initialize. (Perl lets you do this.) The previous normal practice for SPOPS was to define a class with your custom behavior and bring it in using the 'code_class' configuration key. This is such an ugly hack I shouldn't even discuss it :-) > BTW, do I understand correctly that links_to objects are loaded in a > lazy manner, that is, they are not fetched until the method to access > them is explicitly invoked? Correct. I have a strong aversion to systems that load dependencies automatically because you wind up fetching a huge graph when you want a simple object. Chris -- Chris Winters Creating enterprise-capable snack systems since 1988 |