The web in a box - a next generation web framework for the Perl programming language

IRC log for #mojo, 2018-01-27

| Channels | #mojo index | Today | | Search | Google Search | Plain-Text | summary

All times shown according to UTC.

Time Nick Message
00:12 tyldis jberger: (re userinfo parsing) my concern comes from this in Mojo::URL: https://paste.debian.net/1007426/
00:13 tyldis If I urlescape the second example, it works (and also works on the server)
00:14 tyldis You might not be passing -u to Mojo::URL, I haven't checked
00:15 tyldis s/urlescape/urlencode/
00:16 tyldis Sine Mojo::URL seems to urlencode the path on the fly, but not when doing to_string, I find the behaviour a little bit inconsistent
01:02 Leffe joined #mojo
01:27 gizmomathboy joined #mojo
01:46 good_news_everyon joined #mojo
01:46 good_news_everyon [mojo-pg] kraih closed pull request #48: minor fix: allow callbacks to call ->listen, ->unlisten (master...multiple-callbacks) https://git.io/vNkup
01:46 good_news_everyon left #mojo
01:46 good_news_everyon joined #mojo
01:46 good_news_everyon [mojo-pg] kraih pushed 2 new commits to master: https://git.io/vNMIG
01:46 good_news_everyon mojo-pg/master 65df347 Pip Cet: minor fix: allow callbacks to call ->listen, ->unlisten
01:46 good_news_everyon mojo-pg/master 9eff3f4 Sebastian Riedel: Merge pull request #48 from pipcet/multiple-callbacks...
01:46 good_news_everyon left #mojo
02:12 Ralesk joined #mojo
02:56 ilbot2 joined #mojo
02:56 Topic for #mojo is now 🍩 nom nom | http://mojolicious.org | http://irclog.mojolicious.org | http://code-of-conduct.mojolicious.org
03:35 jberger tyldis you are exactly getting this 100% the wrong way around :-P
03:35 jberger the whole point of what I'm doing is setting the userinfo via the method not via string parse
03:35 jberger exactly to avoid the problem you are seeing :D
03:36 jberger I'm not 100% sure that url encoding would actually fix your problem anyway
03:37 jberger the userinfo isn't really url-ish in that way
03:37 jberger but that aside, the point is to avoid the problem you see when using the get command
05:04 dboehmer_ joined #mojo
05:28 Leffe joined #mojo
06:12 tyldis jberger: I know the feature you are working on. Was just making sure that you handle it.
06:15 tyldis And I need to figure out if M::URL has a bug or not. I recently ran into this, and urlencoding worked. But I guess I need to see how the module handles it internally.
06:20 mohawk anyone got ideas on why a Mojolicious::Lite app in a test script can freely have a M::Plugin::OpenAPI, and have a M::Plugin::GraphQL talk to it fine (using non-blocking, in case that matters), but in a full app doing similar in the startup method causes this: "Can't call method "build_tx" on an undefined value" on line 23 of Mojo::Server
06:20 mohawk which is this: my $tx   = $self->app->build_tx;
06:21 mohawk at that point, Data::Dumper shows the M::Server object's "app" attribute to be undef
06:21 mohawk ideas very, very welcome
06:22 mohawk am i right in fearing it's because Test::Mojo etc means it's actually running forked after all?
06:22 mohawk (btw, wrong: actually M::Server::Daemon object)
06:44 Grinnz no, Test::Mojo does not fork
06:44 mohawk great
06:44 mohawk any thoughts on the above?
06:45 Grinnz need more specifics
06:46 mohawk it's this app: https://mojolicious.io/blog/2017/12/22/day-22-how-to-build-a-public-rest-api/
06:46 mohawk with this line in the startup method straight after the OpenAPI plugin:
06:46 mohawk $self->plugin(GraphQL => {convert => [ qw(OpenAPI /api), $self ]});
06:46 mohawk that's literally it
06:48 Grinnz why is it trying to build a response during startup?
06:48 mohawk that's how it currently operates
06:49 Grinnz that cannot work
06:49 Grinnz a mojo app runs startup, and then responds to requests
06:49 mohawk as i suspected
06:50 Grinnz how is it even getting a request during startup? are you sending a request to itself??
06:50 mohawk so it would need to just do non-blocking stuff and then finish its stuff soon as the requests start doing their thing
06:50 mohawk the GraphQL plugin, when it's working on a local server, requests the OpenAPI spec from that server
06:51 Grinnz that won't end well
06:51 Grinnz the plugins can communicate through installing helpers
06:52 mohawk now you say that, i think openapi.spec is such a helper
06:52 Grinnz and a helper, as long as it doesn't need any request data, can be run on the app during startup
06:53 mohawk that makes perfect sense
06:53 mohawk that'll teach me to cargo-cult from OpenAPI::Client (outward-orientated, obviously) for the inward-orientated thing i want here
06:54 mohawk (although confusingly it can operate inwards too, which is what led me astray)
06:55 mohawk what's bizarre is that it works fine in the test for GQL::Plugin::Convert::OpenAPI
06:56 Grinnz OpenAPI::Client isn't an app, it talks to a local app much like Test::Mojo does
06:56 Grinnz an app trying to request itself is different
06:57 mohawk sure
06:57 mohawk but if one is new to Mojo*, that's quite a fine hair to split
06:57 mohawk until, to dizzyingly switch metaphor, it bites one in the bum
06:58 mohawk hopefully final question: a helper can be called on the app itself?
06:58 Grinnz yes, helpers can be called on the app or a controller
06:58 mohawk superb
06:59 Grinnz when called on the app, it will instantiate a default controller object for the invocant, but obviously that controller object wont have a transaction
06:59 mohawk sure
06:59 mohawk but since it will not need to do tx's, that's just fine
06:59 mohawk Grinnz, thanks for the help! i will report back manana since here it's quite late
07:02 mohawk thinking out loud here, there is the deeply unlikely scenario that one app could have >1 openapi installed on it. i wonder which one "openapi.spec" would return. i guess the last-installed one?
07:02 mohawk i'll burn that bridge when i come to it
07:03 Grinnz yes, defining a helper again would replace it
07:03 Grinnz maybe you need to namespace the helper by where it gets installed routing-wise somehow?
07:04 mohawk for today, it's not a problem
07:04 mohawk and it's batman's module, not mine, which doesn't have any helpers yet
07:05 Grinnz 'deeply unlikely' is probably good enough for now :P
07:06 mohawk time will tell :-)
07:21 mohawk dangit, $app->openapi->spec is returning undef
07:41 mohawk looks like M::P::OpenAPI *does* handle multiple installations on it - and the openapi.spec helper relies on figuring which one from $c->req->url->path->to_string
07:41 mohawk :'(
07:43 mohawk so i'd need to put together a controller that's got the right request URL
07:43 mohawk and call the helper on that
07:44 mohawk aha
07:44 mohawk the ->req method requires a tx
07:48 Grinnz yeah, none of that would make any sense until you have a request
07:48 Grinnz if you could tell which installation it's for you could cache them per installation
07:48 Grinnz unless the openapi plugin already does
07:49 mohawk not really
07:50 mohawk you have to tell the GQL plugin which one it's for, so i'll use that and just put together enough of a tx to satisfy openapi
07:50 Grinnz bit of a hack, maybe you could ask batman to give you a better way to specify it :)
07:51 mohawk help me, superman
07:51 mohawk s/superman/batman/ # ;-)
07:52 mohawk if there is such a way, it's not obvious
07:53 mohawk but there may be in due course after we've had a pow-wow
07:53 mohawk now how do i make a real controller that knows about the stash values from its app...
07:54 Grinnz they're just objects, but there's a lot of internal setup between them that isn't designed to be done manually
07:54 Vandal joined #mojo
07:54 Grinnz hence bit of a hack...
07:54 mohawk you are not wrong
07:55 Grinnz i'd start by looking at how the server builds the tx
07:56 mohawk good call
07:58 mohawk there's an app->build_tx, which is handy
08:00 mohawk ...but literally just returns Mojo::Transaction::HTTP->new
08:00 mohawk great
08:01 mohawk something tells me a new helper 'openapi.spec_for_url' is called for
08:02 Grinnz sounds reasonable
08:02 mohawk _for_path, in fact
08:38 AndrewIsh joined #mojo
08:53 mishanti1 s/use Moose;/use Mojo::Base -base;/g  <-- feels good!
08:54 mohawk starts quicker? ;-)
08:54 mohawk i'm going for spec_for_uri in fact
08:54 mishanti1 Hehe, that it does, but it is just so much more elegant.
08:54 Grinnz as long as you weren't using a bunch of Moose features... :P
08:54 bianca joined #mojo
08:55 mishanti1 I have been looking at the moose-core. Cthulhu called my name.
08:55 mishanti1 Looking at Mojo::Base feels better by far
08:56 mishanti1 Grinnz: Oh, I have. Composition, roles, _lots_ of coersion etc.
08:56 Grinnz there's something to be said for easily read source code
08:56 Grinnz well luckily roles and types are both easy to do without moose
08:57 mishanti1 I have spent a couple of months slowly building a test-suite for this application, and now I can slaughter the Moose without too many unknowns.
08:57 Grinnz types with Mojo::Base might be tricky though, attributes are a bit too basic
08:58 mishanti1 I have come to the conclusion that for me in this context types did not offer anything, except adding complexity.
08:58 mishanti1 So good riddance.
08:59 mishanti1 Not saying that types don't have their uses, but in this context they are just annoying.
09:00 mohawk i truly want compile-time type-checking
09:03 mishanti1 Being able to "turn it on" for applications that are not under test would be nice, but for the applications that I have under test I don't feel they would give me anyhing.
09:03 mohawk compile-time?
09:04 mohawk you're saying you want to turn off compile-time type-checking for under test? i think i didn't understand
09:06 mishanti1 Sorry for being vague. For applications where I have not written tests it would be nice to "turn on" type checking. For applications where I have written tests I have no use for types.
09:07 mishanti1 s/no use for types/no use for type-checking/
09:08 mohawk fair enough
09:08 mohawk in my experience, type-checking helps avoid dumb bugs
09:08 mohawk and also more subtle ones
09:08 mohawk if there's a performance cost because it's runtime, that's a thing to consider
09:08 mohawk but if it's compile-time...
09:10 Leffe joined #mojo
09:17 dod joined #mojo
09:18 sh14 joined #mojo
09:25 dod joined #mojo
09:36 bianca joined #mojo
09:41 trone joined #mojo
09:42 kes joined #mojo
10:32 CandyAngel What is used to run the Mojo test suite.. prove -r -Ilib?
10:38 good_news_everyon joined #mojo
10:38 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNM4g
10:38 good_news_everyon mojo-pg/master a84b860 Sebastian Riedel: require SQL::Abstract 1.84
10:38 good_news_everyon left #mojo
11:27 sri hmm, one little problem with upserts in SQL::Abstract::Pg
11:27 sri i can't actually auto-select a constraint
11:29 sri INSERT ...  ON CONFLICT (foo) DO UPDATE SET a = 'b'
11:29 sri i need a nice syntax to define foo
11:30 sri which may be a list of constraints
11:38 sri this is very easy to get wrong, i better think a little longer about how to do it right
11:39 sri new SQL::Abstract has just been released to cpan, so upsert is now possible
11:41 sri 🤔
11:43 sri ->insert('...', {...}, {on_conflict => ['name', {foo => 'bar'}]})
11:43 sri i suppose it will have to be something like that
11:44 sri ->insert('...', {...}, {on_conflict => [['id', 'name'], {foo => 'bar'}]})
11:44 sri ->insert('...', {...}, {on_conflict => [['id', 'name'], {foo => 'bar'}, {baz => 'yada'}]})
11:44 sri last one would even include a where
11:45 sri ->insert('...', {...}, {on_conflict => undef})
11:45 sri and that one still works for DO NOTHING
11:50 jamesaxl joined #mojo
11:59 jamesaxl joined #mojo
13:22 sri think for startes i'll just give on_conflict the group_by treatment
13:22 sri ->insert('some_table', {foo => 'bar'}, {on_conflict => \'do nothing'})
13:23 sri then we can see where to go from there
13:51 good_news_everyon joined #mojo
13:51 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMa4
13:51 good_news_everyon mojo-pg/master aafdc0a Sebastian Riedel: add basic support for on_conflict option to insert and insert_p methods in Mojo::Pg::Database
13:51 good_news_everyon left #mojo
13:54 sri i suppose \[] wouldn't be too hard either
13:55 sri ->insert('some_table', {foo => 'bar'}, {on_conflict => \['(id) do update set foo = ?', 'bar']})
14:12 brunoramos joined #mojo
14:20 good_news_everyon joined #mojo
14:20 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMVb
14:20 good_news_everyon mojo-pg/master bdc3bd3 Sebastian Riedel: allow literal SQL with placeholders to be passed to on_conflict
14:20 good_news_everyon left #mojo
14:20 sri not every day you get to write @$$ and it's actually reasonable code
14:33 good_news_everyon joined #mojo
14:33 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMrk
14:33 good_news_everyon mojo-pg/master eed4df0 Sebastian Riedel: mention PostgreSQL specific extensions specifically
14:33 good_news_everyon left #mojo
14:36 good_news_everyon joined #mojo
14:36 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMrm
14:36 good_news_everyon mojo-pg/master 24a8d69 Sebastian Riedel: fix formatting error
14:36 good_news_everyon left #mojo
14:41 good_news_everyon joined #mojo
14:41 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMrw
14:41 good_news_everyon mojo-pg/master ca501cb Sebastian Riedel: use a shorter example for upserts
14:41 good_news_everyon left #mojo
14:44 sri i'm open for suggestions to make the most common upsert use cases more user friendly
14:49 sri {on_conflict => ['id', {foo => 'bar'}]}
14:49 sri seems like the most common case
14:54 itaipu joined #mojo
15:12 pirateFinn_ joined #mojo
15:14 good_news_everyon joined #mojo
15:14 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMK4
15:14 good_news_everyon mojo-pg/master 94cf9eb Sebastian Riedel: turn array references passed to group_by into a list of fields
15:14 good_news_everyon left #mojo
15:15 sri getting the hang of it
15:19 sri _SWITCH_refkind is fairly useful for making error messages consistent
15:24 * sri likes the SQL::Abstract code a whole lot more than DBIx::Class::SQLMaker
15:30 karjala_ joined #mojo
15:35 good_news_everyon joined #mojo
15:35 good_news_everyon [mojo-pg] kraih tagged v4.06 at d73ed33: https://git.io/vNMiI
15:35 good_news_everyon left #mojo
15:35 good_news_everyon joined #mojo
15:35 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMiL
15:35 good_news_everyon mojo-pg/master d3c3fed Sebastian Riedel: bump version
15:35 good_news_everyon left #mojo
16:07 jberger @$$ ?
16:07 jberger the array dereference of the process id ?! ;-P
16:08 nicomen IMHO: @{ ${ $arrayrefref } } > triple-sigils
16:09 jabberwok triggles?
16:10 nicomen perl 7
16:11 itaipu joined #mojo
16:15 ribasushi nicomen: I refuse to believe you do not find this stunningly charming: https://metacpan.org/source/RIBASUSHI/DBIx-Class-0.082840/lib/DBIx/Class/SQLMaker.pm#L430
16:22 nicomen My brain capacity is too low to parse that :-/
16:23 nicomen but both examples mojo and yours help the next developer noticing it might not be a typo at least, by having ARRAYREFREF and the explicit condition check nearby
16:23 itaipu joined #mojo
16:47 marty joined #mojo
17:08 sri hmm, i suppose i could add ->insert(..., {on_conflict => undef}) # DO NOTHING
17:08 sri and maybe ->select(..., {for => 'update'}) # FOR UPDATE
17:08 sri since those should be not too uncommon
17:14 sivoais joined #mojo
17:17 good_news_everyon joined #mojo
17:17 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMDO
17:17 good_news_everyon mojo-pg/master 5a2994f Sebastian Riedel: add shortcut for "DO NOTHING"
17:17 good_news_everyon left #mojo
17:28 Leffe joined #mojo
17:35 good_news_everyon joined #mojo
17:35 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMyt
17:35 good_news_everyon mojo-pg/master 6441450 Sebastian Riedel: add shortcut for "FOR UPDATE"
17:35 good_news_everyon left #mojo
17:37 sri ok, now all new option keys at least have one non literal sql use case :)
17:38 sri still would like a nice upsert syntax
17:44 good_news_everyon joined #mojo
17:44 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMyQ
17:44 good_news_everyon mojo-pg/master 702d049 Sebastian Riedel: show the rejected value
17:44 good_news_everyon left #mojo
17:46 ChmEarl joined #mojo
18:00 Leffe joined #mojo
18:16 good_news_everyon joined #mojo
18:16 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNM97
18:16 good_news_everyon mojo-pg/master cd07e1e Sebastian Riedel: make upserts look nice
18:16 good_news_everyon left #mojo
18:16 sri :D
18:22 sh14 joined #mojo
18:23 bianca joined #mojo
18:40 mishanti1 sri: Feeling good? :)
18:48 ladnaV joined #mojo
18:51 bianca joined #mojo
19:13 sri of course, i just finished a big feature
19:13 sri now i'm wondering how we could support joins
19:32 good_news_everyon joined #mojo
19:32 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNMds
19:32 good_news_everyon mojo-pg/master 84dc9b3 Sebastian Riedel: puke more efficiently
19:32 good_news_everyon left #mojo
19:36 sri are there any SQL::Abstract subclasses that have done joins well?
19:39 nicomen I use SQL::Abstract::Complete, "well" is highly subjective, if you find something easier to use, I'd like to know
19:40 sri that looks horrible :S
19:48 nicomen yeah...
20:34 bianca joined #mojo
20:56 sri i want a nice syntax for defining joins, i mean, it can't be that hard
20:58 mohawk looked at JS modules that do this sort of thing?
20:58 sri ->select(['foo', ['bar', {id => 'id'}], ['baz', {id => 'id'}]], '*', ...)
20:58 mohawk cf sequelize
20:58 sri most use method calls instead of data structures
20:59 sri ->table('foo')->join('bar', ...)->select('*')->...
20:59 mohawk mm
21:00 sri we could build that easily around SQL::Abstract, but as a first step we need a data structure that doesn't totally suck
21:00 mohawk sure, i'm all about the data-driven
21:04 sri actually, i guess i'd just make the data structure simpler
21:04 sri ->select(['foo', ['bar', 'bar_id', 'id'], ['baz', 'baz_id', 'id']], ...)
21:05 mohawk named params might be better than positional?
21:05 sri then preprocess the arrayref and remove the nested arrayrefs, and let SQLA handle the rest
21:06 sri re other languages, this one seems to be the one most people agree on liking https://github.com/jeremyevans/sequel
21:08 sri yea, i think i like that structure
21:09 sri ->select(foo => ['bar', bar_id => 'id'], ...)
21:09 sri oops
21:09 sri ->select([foo => ['bar', bar_id => 'id']], ...)
21:11 sri and it leaves room for more options, like join type
21:13 mohawk that looks not too shabby
21:13 mohawk reading the "sequel" example, doesn't look like it has huge support for prepare, then execute with placeholders
21:14 sri if you looked at Mojo::Pg from an outside perspective it would look the same
21:14 sri when in fact it does so magically behind the scenes
21:16 mohawk fair enough
21:16 mohawk i'm just wondering whether there's an opportunity to make such magic more comprehensible to implement :-)
21:22 sri ->select(['foo', ['bar', 'bar_id', 'id', 'left']])
21:22 * sri wonders if that's good enough
21:23 sri ->select(['foo', ['left', 'bar', 'bar_id', 'id']])
21:24 sri ->select(['foo', ['bar', 'bar_id', 'id', {left => 1}]])
21:24 sri ->select(['foo', ['bar', 'bar_id', 'id', {join => 'left'}]])
21:24 sri ->select([foo => ['bar', bar_id => 'id', {join => 'left'}]])
22:22 karjala_ joined #mojo
22:25 cromedome joined #mojo
22:40 good_news_everyon joined #mojo
22:40 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNDfF
22:40 good_news_everyon mojo-pg/master 71bf0a2 Sebastian Riedel: add support for INNER JOIN
22:40 good_news_everyon left #mojo
22:44 Grinnz neat. probably want to support arbitrary join conditions, i guess a scalar ref would be appropriate for that?
22:45 sri yes, i'd want to be absolutely sure about the basics before i add more though
22:45 ribasushi sri: having the condition columns as position elements will be rather nightmare-ish when you have multi-column FKs
22:46 ribasushi *positional
22:46 Grinnz that's why i mention arbitrary join conditions... i have a looot of weird ones at $ork
22:46 sri ->select(['foo', ['bar', \'(...arbitraty conditions...)']])
22:47 sri i'm very unsure about where to fit in the join type though
22:47 ribasushi sri: also beware being trapped into "oh, I will just allow [ foo, { far.col => near.col } ], as that then makes "use arbitrary sqla structure" ... difficult
22:52 sri i'm not going to try and make custom data structures for uncommon cases
22:53 sri literal SQL conditions is good enough for those
22:53 sri "table name, col1, col2, join_type"
22:53 sri that's the most complicated case that gets a special data structure
22:54 ribasushi as long as that's an acceptable tradeoff ( single-column relations ) - then sure, it makes sense
22:54 sri advantage of targeting humans with this, and not an ORM :)
22:55 sri just need to fit in the join type somewhere :/
22:56 sri ->select(['foo', ['bar', 'foo_id', 'id', 'left']])
22:56 sri ->select(['foo', ['bar', \'(...conditoon...)', 'left']])
22:56 sri if there are no better ideas i'll go with that
22:59 nicomen some hours ago I was wondering if nesting the joins would make it easier in general and a clear way to add join type or other attrs relating to the join
22:59 nicomen but just shut up as I didn't think it thru ;)
23:01 sri ribasushi: and of course i can always say, just use ->query if you need more power http://mojolicious.org/perldoc/Mojo/Pg/Database#query
23:09 sivoais joined #mojo
23:25 mohawk dammit, scotty!
23:29 good_news_everyon joined #mojo
23:29 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNDTT
23:29 good_news_everyon mojo-pg/master 64c97a9 Sebastian Riedel: allow for the join type to be specified as well
23:29 good_news_everyon left #mojo
23:30 sri this is one of those moments i'll prolly have to link back to in the future when someone asks why i didn't pick a better join data structure
23:30 sri so, here's your reminder that the time to complain is now :)
23:30 * sri pokes jberger, marcus and batman
23:31 sri (although, if i really screw up it's fairly easy to break it and push a major release of Mojo::Pg :p)
23:33 sri guess if i release SQL::Abstract::Pg separately from Mojo::Pg there is no deprecation policy at all
23:36 good_news_everyon joined #mojo
23:36 good_news_everyon [mojo-pg] kraih pushed 1 new commit to master: https://git.io/vNDTi
23:36 good_news_everyon mojo-pg/master 6d27bbb Sebastian Riedel: keep the examples minimal
23:36 good_news_everyon left #mojo
23:47 sri i suppose a -left would be SQLA style too
23:47 sri ->select(['foo', ['bar', 'foo_id', 'id', -left]])
23:47 sri ->select(['foo', [-left, 'bar', 'foo_id', 'id']])
23:48 sri ->select(['foo', [-left => 'bar', foo_id => 'id']])
23:49 sri that last one is not bad
23:50 sri ->select(['foo', ['bar', foo_id => 'id']]) # INNER JOIN
23:50 sri ->select(['foo', [-left => 'bar', foo_id => 'id']]) # LEFT JOIN
23:51 sri Grinnz: what do you think?
23:51 purl I think sri should try flossing more often!
23:52 sri purl: good advice
23:52 purl Good advice: using a CPAN module.  Bad advice: using ALL the CPAN modules.

| Channels | #mojo index | Today | | Search | Google Search | Plain-Text | summary