# so, what we have here is a conversion of the test suite.
# I'm not 100% on the syntax, but I want to get it basically working.
# the first thing I need to figure out is how the hell to get these functions
# exported into Sample::Address and Sample::Employee.
# use base does an @INC frob and a require.
# it does _not_ do a 'use', which means we never call 'import';
package Sample::Address;
# stinks of ingy, but:
use Jifty::DBI::Record '-base';
# *laugh*
I want better syntax than that. hm.
But is the general concept ok?
# maybe. I almost wonder whether we want a separate class for this.
Jifty::DBI::Record->import(), actually ;
# or could be:
Jifty::DBI::Record->inherit; # or something (that means it has to be loaded already)
# Well, sure, import would just work.
# that's just evil. maybe right too.
UNIVERSAL::import.
It works sort of like UNIVERSAL::require.
then you could have
import Jifty::DBI::Record::SchemaFunctions# or something
#not sure I like that, though.
# would you want to have that *and* the use base though?
# no.
# if you're not trying to subclass, then I don't see what's wrong
# with
use Jifty::DBI::Record ':schemafunctions';
# which is standard Exporter.pm (@EXPORT_TAGS or whatever)
*nod*
#it feels a bit unclean. especially given what we're tyring to do.
#
# Yeah, I don't really like having the stuff pollute the namespace either.
# if prototypes worked with methods I wouldn't even mind having to do
$x = Jifty::DBI::SchemaBuilder->new;
$x->define_blablalb
$x->bla bla
# (ok, maybe I'm being influenced by ruby again :) )
# (take a peek at the XML::Builder thing I checked into the SyncML tree sometime
# for a simiarl issue)
# not convinced ruby influence is bad..
# I sort of want to be able to take __PACKAGE__ and make an alias to it
# CLASS-> or something
# you just don't like the word __PACKAGE__ basically?
# let me illustrate.
# that's kind of the Class::DBI syntax, right?
# yeah. and it pollutes everything.
# and it doesn't let you *not* use () or magic sub{}s either :(
# just look at that code. I see __PACKAGE__ and some lowercase stuff near it.
# not "oh look, I have 3 fields"
# yup.
# *evil*
our db_table 'addresses';
our field name => { has_type 'varchar'; has_default 'frank' };
# (by the way, i'm pretty sure we don't get to do the sub-at-t-end thing
# either... I tried lots of hacky ways to get it working and failed.)
# yeah, I think we're going to end up having a pseudo-sub that's really a hash behind the scenes
# uh, ok, sothe ; has to become , probably.
# probably.
# worrying about htat bridge later
# *nod*. So is it ok if db_table, field, etc end up in your model's namespace?
# I think so.
# I'd love to have that not true, but I'm not seeing it
# Well, you probably could... no this is too wrong to imagine.
# yes?
{
my $s = Jifty::DBI::SG->import_functions;
db_table bla bla bla;
field bla;
field bar;
} # $s.DESTROY gets called and unimports db_table/field/...
# actually you might not even need the { } for that as long as nothing
# else in the file ever refers to it.
my $schema = Jifty::DBI::RecordSchema->new;
$schema->for_class(__PACKAGE__); #just riffing
$schema->field name => { has_type 'varchar'; has_default 'Frank'}
#It's not quite metaprogramming enough or something.
I really like the barewords
# I'm not sure you saw what I meant -- you don't need the method calls
my $s = Jifty::DBI::RecordSchema->new;
field name => bla;
__ENDOFFILEHERE__ (it does work, I just tested it). evil though.
# yeah, you're using a destroy hack.
# I'm not sure we need to worry about clearing out the namespace.
# not sure we don't.
# but it feels wrong to have it _stop_ working once the code is running.
# well, it's wronger to modify the schema later :)
# but anyway, what are you blocking on?
# just how to get the functions exported?
vvvvv?
# I was blocking on whether to import the functions from the superclass,
# as it somehow feels dirty.
# oh. whether those functions belonged in Jifty::DBI::Record
# or whether the schema was another object. but having played with that a bit
# I think it results in more code and more disconnected code.
# I think I agree that the record and the schema should be the same object.
# but the "easy declaration macros" could come from somewhere else. maybe
# that doesn't make sense.
# don't forget that after all this fancy sytnax is set up we will still
# need a way to declare schemas programmatically probably.
# it's my expectation that the default sub schema will just read a datastructure that the fancy syntax populates
# cool, that's what i was thinking too. (easiest way to implement too)
# I was planning on lowercasing your hash keys. that make sense?
# sounds good. i had no good reason for them to be in any particular case.
# (it did kind of help make the difference between schema and form_fields
# keys obvious, but that was just a lucky coincidence, not necessarily an
# important feature.)
# less "abusing" and more "never actually defined".
# I've been finding a tiny impedance mismatch with how we do that anyway.
# we're abusing 'type'
# we're using it in two overlapping but incompatible ways ;)
# what do you mean? i haven't poked at that in a while.
# my belief is that the type that you declare in a schema should be a relatively
# high-level description (not worrying about say "time vs timestamp vs datetime"
# say)
# the issue that comes up is "password"
# generally, string fields are all rendered the same way.
# hmm. how do we do that?
# Have a look. I declared a subtype. it's not nice.
# my feeling is that passwords should be a string in the schema but a password
# in a form_fields, probably.
# no, the schema needs to know not to give you a password accessor.
oh, good point. then password should be
# its own SG type :)
# possibly. anyway.
# so. we're back to the import. Let's find a good syntax :)
# i mean, the standard perl way to say "import a bunch of functions" is
use Jifty::DBI::Record ':schema';
#and I read that and don't know what it does.
# No, _I_, have a sense of "oh it imports some functions"
# you've never seen that before? huh.
# but it doesn't read cleanly. it's a relatively unused perl semantic that I
# don't like.
# it may not be clean but it's perl
# lots of things are perl. that doesn't make them right.
# fortunately, if you can come up with anything to put into this blank:
vvvvv
use Jifty::DBI::Record ;
# we can make it work. (including leaving it blank)
# i feel like any statement other than a "use" or an explicit "import"
# bringing functions into my namespace is unexpected and scary. (even
# if it's better english grammar or something :) )
*nod* So, I _don't_ expect either a use or an import to mess with my inheritance chain.
# except for use base, right.
# sorry, yes. I don't expect another module.
# well, i mean, there's always
use base 'Jifty::DBI::Record'; # set up inheritance
Jifty::DBI::Record->im_gonna_be_describing sym;
# it should not be two statements.
# this is what I've been trying to figure out.
# yeah, but i think your constraints that you've said are contradictory
# (1) should not be two statements
# (2) only 'use base' should change inheritance
# not what I think I said. "regular 'use' statements shouldn't mess with inheritance'
# *nod*
# (3) only use or something more explicit should export
Anyway.
# (ok, admittedly *I* said 3 :) but i think you agreed)
# I'm not strong on 3.
I wonder if I can force Jifty::DBI::Record to export into the current package's namespace when used, if and only if it's a subclass.
When you say "when used" do you literally mean "when *use*d" or just "when you start calling functions in it" ?
I guess you could make that work with
BEGIN { @ISA = 'Jifty::DBI::Record' }
use Jifty::DBI::Record; # but this sucks!
use base qw/Jifty::DBI::Record/;
__PACKAGE__->schema_version (0.0001) # or some other method that
# does two thing evilly.
# but you already told me that 'use base' doesn't call import.
# ah, that could work. (i could believe it being __PACKAGE__->db_table)
# except I want to be able to intuit that from classname
# unless it's explicit.
# will base let me pass anything in? time to hit source
# i'm hitting it, and basically no. in fact once the base class
# has been required once in your program's execution, all that
# future use base calls is going to do is a push @package::ISA, $base_class;
# we could tie @ISA
#I'm kidding
# we could replace base::import to do interesting things for classes that
# match /^Jifty/ (it would be invisible too. and wrong.)
# no, that's an ingy trick.
# nah, i think ingy just makes you not use base. i think ours is more wrong :)
#He actually replaces base:: on the fly
# he showed me.
# uch. never mind then.
# we could just do another use statement
# let me type, dude ;)
# i still kind of feel like what you want is "i want perl to act like
# not perl, but without any evil hacks" which seems tough.
# yes.it's hard. possibly impossible. but if we can make it go, we win.
# I don't mind two use statements. especially since we might be having
# some records that don't use the special syntax
use base qw/Jifty::DBI::Record/;
use Jifty::DBI::Recordblablabla;
or even:
use base /Jifty::DBI::Record/;
Jifty::DBI::Record->define_schema();
Jifty::DBI::Record->columns_from_code(); # instead of ->columns_from_db();
# but maybe a better name for it.
#
# yeah, that's good. I'd like that.
# that seems the least insane so far.
# but what do we call the method?
# schema is perhaps a poor choice of word.
Jifty::DBI::Record->
# i don't like columns, since we're defining foreign keys etc in the schema
# but you see why it makes me twitch?
# i do like the _from_code vs _from_db, since then you can also have
# _from_hash etc etc
*nod* Let's see how it plays:
# I really, really want to be able to define my own subroutine like structures
# well... :
# Class and instance method
use base 'Jifty::DBI::Record';
Jifty::DBI::Record->___from_code();
db_table 'addresses';
# legal! # AUTOLOAD? yup. # not sure that's ok. # also, not intuitive, i think.
# and "code that is really a hash but looks like code" is?
# at least the code that looks like code isn't embedding the column name in a sub call.
# i just don't like it.
# and I don't actually want it to be a hash.
# I just haven't figured out a better way yet.
# *nod*
field {
called 'name'; # ?
# don't really like that, mostly because it's again hard to skim for.
# are you just trying to get the {} block first?
# basically.
# *nod*
# I want infix subs
# well, you're not going to get it, without "sub " or source filters
# (or switching languages :) )
# "we'll see"
# part of this is to see how far I can get. since I know what "feel"
# i want.
# well, there's one bit of hope for getting infix subs actually
# or, well, not really. you can get infix subs but you need to
# but some weord there. by which point that word might as well
# be "sub". OK, what you just wrote will work. (if you like it)
# (well, except for needing a stupid semicolon on the end :( )
# It's not my favorite.
# but yeah, falls into the "works" category"
# and
has_type 'string'
# is definitely better than
type => 'string'
# in your book?
# how would you do:
refers_to_many RT::Tickets by 'owner';
# hmm. i thought about this before. we can do like simon and
refers_to_many "RT::Tickets by owner";
# but I don't really like that. parsing is lame.
# yeah, that's not ok.
# see also "a pub has beers on taps"
# I'm *pretty* sure that we can't get the line you've written to compile.
# *maybe* by putting stuff into package 'by', but that's awful.
unless it's
RT::Tickets->refers_to_many(by(owner));
so you need to do
sub by; i guess
# pretty sure you gave me something similar.
# oh no, autrijus gave me the one line I needed.
# don't forget that RT::Tickets is a class/package.
# shit! it actually works!!!
# yeahi think i did but i didn't believe in it :)
# although the code is running in the wrong place. but you
# can figure out the right class using caller.
# the idea is that it just returns a key, val pair. so it doesn't matter.
# well, right, but refers_to_many is being called in RT::Tickets
# instead of in the current package. but that's ok.
23:46 <obra> I've got a bad perl5 idea for you. Robert claims it's impossible
23:47 <obra> I'm trying to make the syntax "refers_to_many 'BTDT::Model::Tasks' by 'owner';" valid perl5 syntax.
23:47 <obra> I think I want "reverse overload" to make it go. But yeah. not possible.
23:47 <obra> We think
Day changed to 07 Aug 2005
03:57 <autrijus> well, that may be true but you don't want that.
03:57 <autrijus> refers_to_many BTDT::Model::Tasks by 'owner'
03:57 <autrijus> is more readable and easily implemented.
03:58 <autrijus> sub by ($) { by => @_ }
03:58 <autrijus> done!
03:58 <autrijus> stop thinking classes as strings :)
# so, now we're just still on the
field foo => sub {}; issue
# let's see what the hash syntax looks like with my weird keys.
# actually i think i may need to go.
# i'll leave this open for a bit if you want to type, but save it?
# I'm going to switch back to vim, where I can code. But I'll check in these notes.
# ok. later.
field email => sub {
has_type 'varchar';
has_default 'Frank';
};
field phone => {
has_type 'varchar';
};
field employee_id => {
refers_to_a Sample::Employee;
}
package Sample::Employee;
use base qw/Jifty::DBI::Record/;
__PACKAGE__->db_table 'employees';
__PACKAGE__->field name => has_type 'varchar';
__PACKAGE__->field dexterity => { has_type 'integer'};
1;