Re: DBI v2 - The Plan and How You Can Help

2005-07-06 Thread Steve Sapovits

Maxim Sloyko wrote:

I don't think this solves the problem, because what I usually want is 
the user to be able to use the application, but unable to see the DB 
password. So the user should have read permission set for the file, 
but on the other hand he shouldn't. It's not not a problem for Web App, 
though.


Storing passwords encrypted, decrypting before using doesn't cover this?
I've played around with Crypt::CBC (and different ciphers) for this sort
of thing but admittedly have not applied this to any production systems
yet.  You still have a key somewhere to hide/obscure.  You can also use
Perl source filters to totally encrypt the source -- something else I've
done but not in production.  Just some things you may want to look at ...

--
Steve Sapovits  [EMAIL PROTECTED]


Re: Submethods

2005-07-06 Thread TSa (Thomas Sandlaß)

Stevan Little wrote:
The concept of non-inherited infrastructural methods is fairly simple to 
accomplish in the meta-model, by just giving submethods their own 
dispatch table inside the metaclass. However where I am somewhat 
confused is in how and when they get called.


I think the question is posed a bit confusingly. Since as you point out,
when the invocant is clear, calling the (sub)method is an easy lookup in
its vtable with subsequent call.



Take this example for instance:

class Foo {
method bar () { ... }
submethod bar () { ... }
}

Is this an error (Synopsis 12 seems to indicate it is *not* an error)?


The only inconvenience I see is that the name Foo::bar is not unique.
The sigil doesn't disambiguate because in both cases it is Foo::bar.
Furthermore the :() is used only to distinguish different sigs, not the
Code subtype behind the name. Hmm, or is this a special cased two-entry
MMD table? One entry for bar:(Foo) and one for bar:(MetaClass[Foo])?


When I call bar() on an instance of Foo, which is called? The method? or 
the submethod? Is it somehow dependent upon the calling context? (called 
from within the class, or from outside the class). Take for instance, 
this example:


class Foo {
method bar () { ... }
submethod bar () { ... }

method baz ($self:) {
$self.bar() # which one does this call?
}
}


I think this is pretty clear. There is exactly one class object Foo
but many instances. The submethod can only be called on the Foo class
object which is available through the .meta method. Thus to call
the submethod one needs $self.meta.bar(). I doubt the usefullness
of falling back to submethod lookup in the class chain when an object
doesn't have the method.

There's actually no syntactical distinction possible because of:

my $object = new Foo;
my $meta = $object.meta;

$meta.bar() # calls submethod but looks like method call

I guess the type of $meta is Ref of Class or somesuch.


Regards,
--
TSa (Thomas Sandlaß)




Re: SMD is for weenies

2005-07-06 Thread Piers Cawley
Yuval Kogman [EMAIL PROTECTED] writes:

 On Fri, Jul 01, 2005 at 13:42:34 +1200, Sam Vilain wrote:
 Yuval Kogman wrote:
 As I understand it SMD is now not much more than a mechanism to
 place a constraint on the MMD, saying that there can only be one
 method or subroutine with the same short name.
 Why is this the default?
 
 Otherwise you lose this quite useful warning if the signatures didn't
 match;
 
 method foo redefined at ...

 That's a good point...

 I'm guessing that the default warnings should have a warning for MMD
 methods which append to a short name without appearing immediately
 after each other in the same file.

 I agree with you MMD is very cool, and I use it a lot.  But I don't
 mind clarifying the intent with multi; this overloading is
 considered by some to be surprising to new programmers.

 Prepending 'mutli' is not a problem when I have to type it. It's a
 problem when others won't type it. When 90% of the module code I'll
 be using is not MMD compatible, because MMD is not the default, I
 can't specialize other people's code without editing it (at runtime
 or at the source level).

 Overloading won't happen unless people overloading semantics are
 introduced, and that's exactly what I'd like to do to other people's
 code occasionally.

Then write yourself a module, call it 'multiplicity' say, which would allow you
to say  

use multiplicity;

sub foo (...) {...} # foo is a multimethod, even if there's already a 'SMD'
# foo in existence.

It shouldn't even be that hard, just macroize sub/method/whatever to become
multis that first check if there's already a singly dispatched sub with the
same name and promoting to multi status if possible. 

Of course, if you use something like that, you're taking the risks on your own
head, but you knew that as soon as you typed 'use multiplicity'. 

The important thing is that the dispatch and reflection system should be
flexible enough to allow you to write something like this.


Re: Type variables vs type literals

2005-07-06 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

Well, there's something to be said for that, but my gut feeling says
that we should reserve the explicit generic notation for compile time
processing via roles, and then think of run-time lazy type aliasing


Could you explain what exactly 'run-time lazy type aliasing' is?
I mean what does it achieve and how does it compare to type
instanciation and parametric contraint checking?



as something a little different.  So if you really want to write
that sort of thing, I'd rather generalize roles to work as modules
containing generic subs:

role FooStuff[T] {
sub foo (T $x, T $y) { }
...
}

Otherwise people are tempted to scatter generics all over the
place, and it's probably better to encourage them to group similarly
parameterized generics in the same spot for sanity.  It also encourages
people to instantiate their generics in one spot even if they're
calling them from all over.

[..]

I think people should say does FooStuff[Int] and automatically alias
all the routines to the Int form so we don't have to scatter :[Int]
all over.  Or if they just say does FooStuff, they get lazily-bound
type parameters.


I get that right, FooStuff can be instanciated without a class or object?
Something like unary operator does? Into which scope do these role 
instanciations go? Does does *FooStuff[Int] mean global?




: ::T $x := $obj;
: my T $y = $x;
: 
: The prime use of that feature is to ensure type homogenity for

: temporary and loop vars in a certain scope. But the scope in the
: above syntax is not apparent enough---to me at least.

Actually, I was holding those up as bad examples of scope visibility,
so I'm agreeing with you there.  (Which is why I suggested that we
require a my context, even if only implied by the formal paramter list.)

: Thus I opt for an explicit
: 
:subtype T of $obj.type; # or just $obj perhaps?

:T $x := $obj;
:my T $y = $x;

Yuck.  I think that completely obscures the lazy type binding.
Plus you've managed to omit the my, so you've created a global
subtype T.  (Unless, as I'm leaning towards, we make such bare inner
types illegal, and require my, our, or *.)


The only thing I did was to replace the :: sigil with a subtype
declaration. Does subtype always go into global scope? I thought
that it requires a *name to go into global and our to go to the
innermost module---or was that package? I mean even non-declared
auto-vivified vars go into the immediately surrounding scope,
or am I horribly mistaken?

sub foo()
{
   if (1) { $x = 'from above' }
   if (2) { say $x }  # prints 'from above' even if no outer $x exists?

   say $x; # prints undef or 'from above' if outer $x
}


Up til now I assumed that ::T and plain T mean exactly the same if T
is pre-declared/defined. The type sigil is only needed to defer the
definition/binding. In a certain sense this is a hanging type reference
similar to foo beeing a reference to Code. Which brings me to the
question how to bind a type reference. I mean we have

my fooref := foo

which allows fooref() calls, right? How are type references derefed
if not by dropping the sigil? ::TypeRef() perhaps?

my ::TypeRef; # type variable?

sub make ( ::Type, Type $value ) returns Type
{
   if (::TypeRef != ::Type)
   {
  ::TypeRef = ::Type;
   }
   my Type $x;
   $x = $value;
   return $x;
}

my $i = make(Int, 17);
my @a = make(Array, [1,2,3]); # single element array?
  # or three element array?

my $e = make(Int 'string'); # type error in make?

With the automatic binding of a ::Type variable to the type
of it's argument the definition of make could be shortend to

sub make ( ::Type $value ) returns Type
{ ... }

and called like this

my $i = make(17);

which at least prevents type errors ;)


Regards,
--
TSa (Thomas Sandlaß)




Re: SMD is for weenies

2005-07-06 Thread Yuval Kogman
On Wed, Jul 06, 2005 at 12:58:44 +0100, Piers Cawley wrote:

 Then write yourself a module, call it 'multiplicity' say, which would allow 
 you
 to say  
 
 use multiplicity;
 
 sub foo (...) {...} # foo is a multimethod, even if there's already a 
 'SMD'
 # foo in existence.
 
 It shouldn't even be that hard, just macroize sub/method/whatever to become
 multis that first check if there's already a singly dispatched sub with the
 same name and promoting to multi status if possible. 
 
 Of course, if you use something like that, you're taking the risks on your own
 head, but you knew that as soon as you typed 'use multiplicity'. 
 
 The important thing is that the dispatch and reflection system should be
 flexible enough to allow you to write something like this.

The issue is cultural, not technical.

If people expect SMD, use it, rely on it, MMD is just another
esotheric feature. Newbies' code will not exploit. Most of CPAN will
not be ready for it.

I won't write me such a module because it'll be more headache than
benefit - explaining to everyone that in my code I like everything
MMD.

What I'm claiming is that MMD like behavior should be the norm. When
it's not appended with true multiness, it's functionally identical
to SMD.

The issue is that extending another person's module with a
multimethod, and using type/parameter dispatch in order to
help code evolve better over time will never be a good or normal
thing to do if it feels kludgy.

My claim is that it doesn't need to feel kludgy.

A macro library kludging over a kludge is twice as kludgy as it was
before.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me does a karate-chop-flip: neeyah!!



pgpxgy79xINw9.pgp
Description: PGP signature


This week's summary

2005-07-06 Thread The Perl 6 Summarizer
The Perl 6 summary for the week ending 2005-07-05
My, doesn't time fly? Another fortnight gone and another summary to
write. It's a hard life I tell you!

This week in perl6-compiler
  Where's everyone gone?
It seems that most of the Perl 6 compiler development is being discussed
at Hackathons and IRC, and summarized in developers' weblogs. What's a
summarizer to do? For now, I'll point you at Planet Perl 6, which
aggregates a bunch of relevant blogs.

http://xrl.us/gn5n

  PGE now supports grammars, built-in rules
Allison Randal raved about the totally awesome PGE grammar support. I
doubt she's alone in her enthusiasm.

http://xrl.us/gn5o

  Multiple implementations are good, m'kay?
Patrick discussed the idea of a 'final' Perl 6 compiler, pointing out
that it isn't clear that there needs to be a final compiler. So long
as multiple implementations are compatible...

http://xrl.us/gn5p

Meanwhile, in perl6-internals
  New calling conventions
Klaas-Jan Stol asked a bunch of questions about the new calling
conventions and Leo answered them.

http://xrl.us/gn5q

  Parrot Segfaults
What's a tester to do? You find a bug that makes Parrot dump core, so
you write a test to document the bug and make sure it gets fixed. But
the test leaves core files lying about. It goes without saying that
Parrot should never dump core without the active assistance of an NCI
call or some other unsafe call blowing up in its face.

Which makes it a little embarrassing that PIR code generated by Pugs can
cause a parrot segfault, though that appears to have been caused by
mixed up calling convention style in the generated call.

http://xrl.us/gn5r

http://xrl.us/gn5s - Brian Wheeler's segfaulting Pugs script

  Python PMCs
Leo pointed out that the various dynclasses/py*.pmc parrot support PMCs
don't yet support all the semantics that Python needs. He outlined some
outstanding issues announced that, as calling conventions and context
handling were changing he'd be turning off compiling py*.pmc for the
time being.

http://xrl.us/gn5t

  PGE bug
It appears that the upcoming changes in Parrot's context handling tweak
a bug in PGE. The discussion moved onto a discussion of PGE's
implementation strategy, Nicholas Clark was keen to make sure it didn't
repeat some of the Perl 5's regex engine's infelicities. While this
discussion continued, Leo spent half a day with gdb and tracked down the
problem, which turned out to be that a register wasn't getting
initialized in the right place.

http://xrl.us/gn5u

  Left-recursive grammars are bad m'kay?
While experimenting with PGE grammars, Will Coleda managed to write a
left-recursive grammar that blew Parrot's call stack with impressive
ease. Luke apologized for things blowing up so spectacularly, but
pointed out that left-recursive grammars weren't supported, and showed a
rewritten grammar that didn't have the same problem (but which doesn't
appear to match the same expressions).

http://xrl.us/gn5v

  Coroutines
Leo pointed to a summary of coroutines, and noted that we still hadn't
defined the syntax of Parrot coroutines, especially with respect to
argument passing. He discussed it with Matt Fowles and solicited a set
of tests that expressed the semantics they came up with.

http://xrl.us/gn5w

ftp://ftp.inf.puc-rio.br/pub/docs/techreports/04_15_moura.pdf

  ParTcl, Perl6 Grammars
Will Coleda announced that, thanks to Matt Diephouse's work, ParTcl (Tcl
on Parrot) is now able to run part of tcl's cvs-latest test suite. The
tests aren't fully native yet, they're currently driven through a Perl
test harness and only passing 10% of the tests, but hopefully the
situation will improve and ParTcl will end up able to run the tests
completely natively (while passing far more of them). Congratulations on
the work so far though.

http://xrl.us/gn5x

  Python and Parrot
Kevin Tew popped up to say that he too is working on a Python compiler
targetting parrot and wondered how to handle things like Python's self
parameter. Michal Wallace and Leo chipped in with suggestions.

http://xrl.us/gn5y

  Another month, another release
Has it really been a month? Seems so. Parrot walked through the
traditional feature freeze, code freeze before being released on Sunday.
The latest release is called 'Geeksunite', referencing the website that
discusses Chip's problems with his former employer. You should
definitely visit the Geeksunite site -- Chip needs our help.

http://xrl.us/gn5z

http://geeksunite.org/ -- Support your local Pumpking

  lower in default find_name scope
Patrick posted a code fragment whose output surprised him -- it turned
out that looking up lower as a name in the default scope returns an
NCI object. 

Re: Submethods (+ suggestion/proposal/idea)

2005-07-06 Thread Stevan Little

Thomas,

On Jul 6, 2005, at 10:19 AM, TSa (Thomas Sandlaß) wrote:
S12 says in the section Submethods: A submethod is called only when a 
method call is dispatched directly to the current class.


And without finding a reference I think it was said that the invocant
of a submethod is a class object.


I took that statement to mean that methods were not inherited, and that 
they can only be called from methods within the class they were 
defined.



From this I have derived what I said. Nonetheless there seems to be
some overlap in particular in the construction process which is
characterized as involving an unitialized object. So in that case
some macro magic might make the instance available to the submethod.
But this will be a non-invocant parameter.


This is a possibility, however, i think that submethods are more 
valuable if they dealt with invocants rather than just with classes 
(metaclasses).


It seemed to me from A12 that submethods are meant to define an 
interface of some kind, the BUILD/DESTROY submethods being the perfect 
example. However this means that BUILDALL and DESTROYALL need to be 
fairly magical. I say this because BUILDALL would have to extract some 
kind of class list from it's invocant, and call 
$self.SomeClass::BUILD() on each class. And since BUILDALL is 
(supposedly) defined in Object, (and I assume it too is a submethod), 
it becomes critical (in some cases) for Object::new to be called.


=begin RANT/SUGGESTION

While I like the idea of infastructural methods, I think maybe we 
should place more restrictions on them. Ideally the object model itself 
would create a set of these interfaces. One for creation 
(BUILD/BUILDALL) and for destruction (DESTROY/DESTROYALL), and maybe a 
few others. And then the model itself would utilize them, but the user 
would not (easily) be able to add to these submethods.


I think this would greatly simplify the concept of submethods, and also 
allow for more advanced users to add new interfaces to the object 
model. This could (theoretically) allow for low-level manipulation of 
the object model while still making it simple for not-as-advanced users 
to use it easily by just following the interface.


For instance, here is a very simply and naive example of a persistant 
interface of sorts:


Object.meta.add_submethod('FREEZE' = sub { ... });
Object.meta.add_submethod('THAW' = sub { ... });

Object.meta.add_submethod('FREEZEALL' = sub ($self:) {
for $class - $self.meta.get_class_list() {
$self.($class)::FREEZE();
}
});

etc etc etc ...

Then a user could simply define a FREEZE and THAW submethod in each of 
their classes they want to be persistent.


Or something like that :)

=end RANT/SUGGESTION

Anyway, just a thought.

Stevan




But mind the sig!
--
$TSa =:= all( none( @Larry ), one( @p6l ))





Re: Time::Local

2005-07-06 Thread TSa (Thomas Sandlaß)

Juerd wrote:

I think the problem one has is much bigger even if a day *number* is
ever displayed. Then beginning with 1 because that's where most humans
begin counting, is wrong. It's a technical thing, and that should be
kept as simple as possible, and as technical as possible, for easier
compatibility with existing technical things.


As a technical remark I like to point out, that you need 8 time points
to define 7 days. Every day is bounded by two such time points---which are
of course 24 hours apart. This is necessary to get the arithmetic right!
Weekday arithmetic is modulo 7. Or put differently

   $week.end() - $week.start() == $week.length == 7 days

must hold. If e.g. you start your week with Monday than this becomes

   $Sunday.end() - $Monday.start() == 7 days.

The next order of precision in calender arithmetic is the hour *within*
the day, then minutes and seconds. The weeks themselfs are subdivisions
of years. And the scheme is not completely regular in e.g. the Gregorian
calendar---but almost e.g in the Sym454 calendar which only has leap
weeks.

I think, that this type of integer with remainder arithmetic shows up
in Perl6 in other places as well. E.g. chars in strings depending on the
Unicode level and index arithmetic of arrays. Some unification of the
underlying math would be nice, indeed. And that typically involves
starting from 0 and the positive remainder pointing into the day.

Regards,
--
TSa (Thomas Sandlaß)




Re: Submethods

2005-07-06 Thread Larry Wall
On Wed, Jul 06, 2005 at 04:19:40PM +0200, TSa (Thomas Sandlaß) wrote:
: Stevan Little wrote:
: You seem to indicate that submethods are not to be used on instances, 
: and instead to be used on the underlying metaclass. I did not see 
: anything of the sort in (Syn|Apoc)12 or in my (limited) search of the 
: mailing list. Can you point me to that information?
: 
: S12 says in the section Submethods: A submethod is called only when a 
: method call is dispatched directly to the current class.

Ah, you're reading a little too much into an imprecise statement.
The intent is not to limit it to class methods--it's using current
class to be inclusive of its members.  It should say something more
like

A submethod is called only when a dispatcher decides to call
a method via this exact class.  This can be because

a) this class, out of all the candidates, happens to be the
class the dispatcher is currently thinking about, or

b) the method call itself is qualified to specify which class
to call explicitly (and for that particular class only, the
constraint on exact class matching is relaxed as if it were
an ordinary subroutine call).  Or

c) you call a submethod as an MMD function, in which case the
first invocant of a submethod is constrained to be an exact
class match, or resolve to an ordinary method.  Or

d) you call it as a qualified function name, in which case it's
a simple function call.

: And without finding a reference I think it was said that the invocant
: of a submethod is a class object.

You won't find that one because I don't think anyone ever said it.

: From this I have derived what I said. Nonetheless there seems to be
: some overlap in particular in the construction process which is
: characterized as involving an unitialized object. So in that case
: some macro magic might make the instance available to the submethod.
: But this will be a non-invocant parameter.

Nope, it's just the normal invocant.  Submethods differ from ordinary
methods only in not being derivable.  (Well, and the fact that they
often operate on partially instantiated objects, as you point out.)

Now in the particular case of a CREATE submethod, you have to get the
class because object isn't created yet.  But generally you don't
need to define one of those unless you don't want to use the built-in
opaque type.  So the usual course of events is that some constructor
(probably called new) calls MyClass.bless(%args) and that in turn
calls

my $newobj = MyClass.CREATE(%args);
$newobj.BUILDALL(%args)

which, after calling all the ancestral BUILDs, calls

$newobj.MyClass::BUILD(%args)

or maybe

$newobj.=MyClass::BUILD(%args)

or possibly even

MyClass::BUILD($newobj, %args)

if it doesn't want to fail over to Object::BUILD in the absence of
MyClass::BUILD.

But all that's behind the scenes.  The basic cargo cult version
for naive users is, Write a 'BUILD' submethod if you want to
initialize the attributes with dynamic data that can't be expressed
with default values.  And write your own constructor if you don't like
the built-in default constructor.  Just make sure your own constructor
calls $class.bless(%args).

Larry


Re: Submethods (+ suggestion/proposal/idea)

2005-07-06 Thread Larry Wall
On Wed, Jul 06, 2005 at 11:28:47AM -0400, Stevan Little wrote:
: It seemed to me from A12 that submethods are meant to define an 
: interface of some kind, the BUILD/DESTROY submethods being the perfect 
: example. However this means that BUILDALL and DESTROYALL need to be 
: fairly magical. I say this because BUILDALL would have to extract some 
: kind of class list from it's invocant, and call 
: $self.SomeClass::BUILD() on each class. And since BUILDALL is 
: (supposedly) defined in Object, (and I assume it too is a submethod), 
: it becomes critical (in some cases) for Object::new to be called.

Most of these submethods will have a generic ordinary method backing
them up in Object.  But Object::new isn't where that magical call to
BUILDALL happens.  It's the SomeClass.bless that does it magically,
and the default Object::new just happens to call .bless.

: =begin RANT/SUGGESTION
: 
: While I like the idea of infastructural methods, I think maybe we 
: should place more restrictions on them. Ideally the object model itself 
: would create a set of these interfaces. One for creation 
: (BUILD/BUILDALL) and for destruction (DESTROY/DESTROYALL), and maybe a 
: few others. And then the model itself would utilize them, but the user 
: would not (easily) be able to add to these submethods.

But we want people to be able to add BUILD methods easily.

: I think this would greatly simplify the concept of submethods, and also 
: allow for more advanced users to add new interfaces to the object 
: model. This could (theoretically) allow for low-level manipulation of 
: the object model while still making it simple for not-as-advanced users 
: to use it easily by just following the interface.

Well, bear in mind that declarators like submethod are just disguised
calls on some metaobject already.

: For instance, here is a very simply and naive example of a persistant 
: interface of sorts:
: 
: Object.meta.add_submethod('FREEZE' = sub { ... });
: Object.meta.add_submethod('THAW' = sub { ... });
: 
: Object.meta.add_submethod('FREEZEALL' = sub ($self:) {
:   for $class - $self.meta.get_class_list() {
:   $self.($class)::FREEZE();
:   }
: });
: 
: etc etc etc ...

Well, sure, except you might want the methods in Object to be
inherited, and use submethods only for specific overrides of the
default.  But the syntax seems a bit klunky.  I suspect it's just
something more like Object does FreezeThawDefault.

: Then a user could simply define a FREEZE and THAW submethod in each of 
: their classes they want to be persistent.
: 
: Or something like that :)

I don't think that's terribly far away from what we've got already.

Larry


Re: Time::Local

2005-07-06 Thread Dave Rolsky

On Wed, 6 Jul 2005, Juerd wrote:


I think the problem one has is much bigger even if a day *number* is
ever displayed. Then beginning with 1 because that's where most humans
begin counting, is wrong. It's a technical thing, and that should be
kept as simple as possible, and as technical as possible, for easier
compatibility with existing technical things.

Calling Sunday 1 and not having a 0 would certainly upset and offend me.

My weeks begin on Mondays, as do most people's weeks here. At the same
time, I can accept any day as the first day if that first day is 0,
because 0 is technical and internal anyway, not meant for humans.

I'm sure lots of people would want an index 1 to be Sunday, if there is
no index 0. This all is solved simply by NOT skipping 0, and using an
arbitrarily chosen day for the first. Or, well, for compatibility,
Sunday :)

Computers and Perl count from 0. People count from 1. If something
begins at 1, it is expected to be a people's thing. And with week days,
this just doesn't work, as not everyone's week starts at the same day.


On reflection, I realized it doesn't matter too much to me.  In the end, 
I'm likely to need a higher-level interface than this to do something 
interesting (like print a day _name_ or calculate the second Sunday of the 
month) and that interface will just use the information Perl's builtins 
give it.



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


Object Creation (was: Submethods (+ suggestion/proposal/idea))

2005-07-06 Thread Stevan Little

Larry,

Okay, I reviewed A12, and I think I have now managed to implement the 
proper object creation behavior in the meta model.


Currently it is somewhat limited, but this is the order of events (as I 
understand it from A12).


- First Object.new calls Object.bless passing all named arguments.

- Object.bless then calls Object.CREATE which then returns a data 
structure for the instance (P6opaque only right now).


- Object.bless then blesses this structure (since the prototype is in 
Perl5 it just passes the structure returned by CREATE into 
CORE::bless(), I am sure it will be different in the proper Perl6).


- Object.bless then calls $instance.BUILDALL (again passing all the 
named params).


- $instance.BUILDALL then does a post-order traversal of the class 
hierarchy calling BUILD on all classes (again passing in the named 
parameters).


Of course CREATE, BUILDALL and BUILD are not proper submethods yet 
because Perl6::Object is not self defining yet. And it only supports 
'P6opaque' right now, but I think I have the ordering of events 
correct, however, please correct me if I am wrong.


Oh yeah, and all that silliness I wrote below,.. ignore it :)

Thanks,

Stevan


On Jul 6, 2005, at 1:45 PM, Larry Wall wrote:


On Wed, Jul 06, 2005 at 11:28:47AM -0400, Stevan Little wrote:
: It seemed to me from A12 that submethods are meant to define an
: interface of some kind, the BUILD/DESTROY submethods being the 
perfect

: example. However this means that BUILDALL and DESTROYALL need to be
: fairly magical. I say this because BUILDALL would have to extract 
some

: kind of class list from it's invocant, and call
: $self.SomeClass::BUILD() on each class. And since BUILDALL is
: (supposedly) defined in Object, (and I assume it too is a submethod),
: it becomes critical (in some cases) for Object::new to be called.

Most of these submethods will have a generic ordinary method backing
them up in Object.  But Object::new isn't where that magical call to
BUILDALL happens.  It's the SomeClass.bless that does it magically,
and the default Object::new just happens to call .bless.

: =begin RANT/SUGGESTION
:
: While I like the idea of infastructural methods, I think maybe we
: should place more restrictions on them. Ideally the object model 
itself

: would create a set of these interfaces. One for creation
: (BUILD/BUILDALL) and for destruction (DESTROY/DESTROYALL), and maybe 
a
: few others. And then the model itself would utilize them, but the 
user

: would not (easily) be able to add to these submethods.

But we want people to be able to add BUILD methods easily.

: I think this would greatly simplify the concept of submethods, and 
also

: allow for more advanced users to add new interfaces to the object
: model. This could (theoretically) allow for low-level manipulation of
: the object model while still making it simple for not-as-advanced 
users

: to use it easily by just following the interface.

Well, bear in mind that declarators like submethod are just disguised
calls on some metaobject already.

: For instance, here is a very simply and naive example of a persistant
: interface of sorts:
:
: Object.meta.add_submethod('FREEZE' = sub { ... });
: Object.meta.add_submethod('THAW' = sub { ... });
:
: Object.meta.add_submethod('FREEZEALL' = sub ($self:) {
:   for $class - $self.meta.get_class_list() {
:   $self.($class)::FREEZE();
:   }
: });
:
: etc etc etc ...

Well, sure, except you might want the methods in Object to be
inherited, and use submethods only for specific overrides of the
default.  But the syntax seems a bit klunky.  I suspect it's just
something more like Object does FreezeThawDefault.

: Then a user could simply define a FREEZE and THAW submethod in each 
of

: their classes they want to be persistent.
:
: Or something like that :)

I don't think that's terribly far away from what we've got already.

Larry





Dependency Injection

2005-07-06 Thread Piers Cawley
So, I got to thinking about stuff. One of the more annoying things about
writing nicely decoupled objects and applications are those occasions where you
want an object to be able to create objects in another class. Say you've
provided a singleton interface to your logging system. The naive implementation
goes something like:

require Logger; 

has $.logger;

method logger { $.logger //= Logger.new }

method whatever {
  ./logger.debug(About to do stuff);
  .do_some_stuff;
  ./logger.debug(Did stuff);
  ...
}

But that's problematic because we've backed knowledge of the particular class
that handles logging into our class. The bad solution to this is to subclass
our class if we want a different Logger class (that conforms to the same
interface). A slightly better solution is to parametrize the logger class
name, probably with a class variable -- but doing that means you have to
remember to set the variable for every class you use. Or you could use a
global, but globals are bad...

It'd be really cool if you could essentially write the naive implementation
above and have your application/test/webserver harness decide which particular
class will be taken to be the concrete implementation. Something like this:

role Logger is Injected { 
  method debug {...}
  method info {...}
  ...
}

Logger::DBI does Logger { ... }

Logger::Debugger does Logger { ... }

Then the harness that actually sets up the application would simply do

use Logger::DBI :dsn..., :user..., :password

and Logger::DBI would install itself as the default Logger class.

The question is, how does one write Injected to make this work? Or what
features do we need to be able to write Injected? Thinking about this, it
shouldn't be too hard to implement 'Injected' in Perl 5:

sub Injected::AUTOLOAD {
  no strict 'refs';
  die If something's already been instantiated you're screwed 
if ref($_[0]) or $Injected::injecting;
  local $Injected::injecting = 1;
  my $target_role = $_[0]
  my @possibles = grep {/(.*)::$/  $1-isa($target_role)} keys %::;
  die Too many possibles if @possibles  1;
  if (@possibles) {
*{$target_role\::} = *{$possibles[0]};
  }
  else {
my $default_package = $target_role-default_class;
eval require $default_package or die Can't find a default package;
*{$target_role\::} = *{$default_package\::};
  }
  {$target_role-can($AUTOLOAD)}(@_);
}

NB, that's completely untested code, but it, or something like it, should work.





   


Re: DBI v2 - The Plan and How You Can Help

2005-07-06 Thread Sam Vilain

Maxim Sloyko wrote:
 But this is not the point. The point was that usage of some file with 
passwords by *DEFAULT* is not the way to go, IMHO. It raises more 
problems than it solves.


Can you give an example of such a problem that wasn't already there?

Just to be clear, the file would only need to contain passwords if the
DBD requires them.

Sam.


Re: Dependency Injection

2005-07-06 Thread Sam Vilain

Piers Cawley wrote:

Then the harness that actually sets up the application would simply do
use Logger::DBI :dsn..., :user..., :password
and Logger::DBI would install itself as the default Logger class.
The question is, how does one write Injected to make this work? Or what
features do we need to be able to write Injected? Thinking about this, it
shouldn't be too hard to implement 'Injected' in Perl 5:


FWIW this is exactly what I would like to achieve with the Date objects;
allowing code that doesn't care about which Date representation they want
the ability to just say any Date representation.

Sam.


Re: Dependency Injection

2005-07-06 Thread Larry Wall
On Wed, Jul 06, 2005 at 11:47:47PM +0100, Piers Cawley wrote:
: Or you could use a global, but globals are bad...

Globals are bad only if you use them to hold non-global values.
In this case it seems as though you're just going through contortions
to hide the fact that you're trying to do something naturally
global.  You might argue that a singleton object lets you hide the
implementation of the delegation from the world, but there's really not
much to implement if you just want to tell the world that whenever the
world says LOGGER the world is really delegating to LOGGER::DBI.
Plus if you really need to reimplement you just vector the world
through LOGGER::SELECTOR or some such.

One nice thing about a variable is that you're guaranteed to
be able to temporize it:

temp $*LOGGER = pick_a_logger();

On the other hand, there's no reason a role can't play with a
global variable, and arbitrate the use of the global among all the
classes that want to delegate through the global.  But a role is not
allowed to function as its own singleton object, because roles don't
define objects.  On the gripping hand, the package holding the role's
namespace is a perfectly fine spot for such singular information.
Every named package/module/class/role/subtype is a kind of global
singleton hash of the symbol table persuasion.

But if globals are inherently bad, we should remove them from Perl 6.

Hmm, this raises the question of whether a role-private class variable
actually belongs in the class's or in the role's namespace:

role Baz {
our $:x;
}
FooBar does Baz;
BarFoo does Baz;

Does $:x end up being a private global in the Baz package or a global
shared between the FooBar and BarFoo packages?  That kinda goes along
with the question of whether attributes in general belong more to the
role or the class into which the role is composed.  It seems like all
those cases can be useful, so maybe we need a syntax to distinguish
role attributes from class attributes.  To think of it another way,
which delarations are to be taken literally, and which generically?
And which way should be the default?

For this particular use, you want some semantics resembling:

role LOGGER {
role:our $:logger handles Any;
role:submethod BUILD ($logger) {
fail Logger already set if defined $:logger;
$:logger = $logger;
}
...

Not necessarily recommending that syntax, of course.  Could just default
declarators to class semantics and force role declaratoins to be explicit:

role LOGGER {
our $:LOGGER::logger handles Any;
submethod LOGGER::BUILD ($logger) {
fail Logger already set if defined $:logger;
$:logger = $logger;
}
...

But that seems a bit klunky, especially given the way package names
and twigils interact.  And don't even think about using $?ROLE there.
Plus we've never let you use our on a qualified name before.

This really seems to be somewhat orthogonal to everything else, so
maybe we need some orthogonal syntax:

role LOGGER {
mumble our $:logger handles Any;
mumble submethod BUILD ($logger) {
fail Logger already set if defined $:logger;
$:logger = $logger;
}
...

for some value of mumble that implies non-generic.  Need to think
about this some more.  I *don't* think it's viable to make non-generic
the default unless we do it only for variables.  But then you'd be forced
to write

our BUILD ::= submethod ($logger) {...}

to get a non-generic BUILD submethod, and that's more than a bit ugly.

So I'm still mumbling...

Larry


Re: SMD is for weenies

2005-07-06 Thread Stuart Cook
It's possible that we could do the following:

1) All subs (and methods) are considered multi 'under-the-hood'.

2) If the first declaration is explicitly 'multi', then you (or
others) can provide additional overloads (using 'multi') that won't
trigger warnings.

3) If the first declaration /doesn't/ use 'multi', then defining
another sub/method of the same name triggers an error/warning. BUT,
later declarations can override this by using some sort of special
declaration.


e.g.

sub foo(Int $x) { ... }
sub foo(Str $x) { ... } # error/warning

multi sub foo(Int $x) { ... }
multi sub foo(Str $x) { ... } # ok

sub foo(Int $x) { ... }
sub foo(Str $x) is overload { ... } # ok; not sure about the trait name


This provides uniqueness checking for SMD subs by default, while still
allowing hardcore hackers to overload other people's subroutines
without their explicit consent.  It's not as clean as Yuval's
suggestion, but I think it might be more acceptable to folks who are
used to SMD.


Stuart