43. EC2 Caveats
Default Perl builds are really bad
(âXLâ instances are great, though)
Machine Setup/Teardown is ~manual
The billing structure is crazy
50. 31b:~ jesse$ perl /tmp/contrived.pl
Undefined subroutine &main::does_not_exist called
at /tmp/contrived.pl line 20.
31b:~ jesse$ vim /tmp/contrived.pl
18.sub c {
19. my $to_call = shift;
20. $to_call = quot;does_quot;.$to_call;
21. no strict refs;
22. $to_call->();
23.}
51. 31b:~ jesse$ perl /tmp/contrived.pl
Undefined subroutine &main::does_not_exist called
at /tmp/contrived.pl line 22.
31b:~ jesse$ vim /tmp/contrived.pl
18.sub c {
19. my $to_call = shift;
20. $to_call = quot;does_quot;.$to_call;
21. no strict refs;
22. use Carp; Carp::cluck(quot;$to_callquot;);
23. $to_call->();
24.}
61. 31b:~ jesse$ perl -MCarp::REPL /tmp/contrived.pl
Undefined subroutine &main::does_not_exist called
at /tmp/contrived.pl line 22.
0: Carp::REPL::repl called at /tmp/contrived.pl:22.
1: main::c called at /tmp/contrived.pl:15.
2: main::b called at /tmp/contrived.pl:9.
3: main::a called at /tmp/contrived.pl:27.
Now at /tmp/contrived.pl:22 (frame 0).
$
63. 31b:~ jesse$ perl -MCarp::REPL /tmp/contrived.pl
Undefined subroutine &main::does_not_exist called
at /tmp/contrived.pl line 22.
0: Carp::REPL::repl called at /tmp/contrived.pl:22.
1: main::c called at /tmp/contrived.pl:15.
2: main::b called at /tmp/contrived.pl:9.
3: main::a called at /tmp/contrived.pl:27.
Now at /tmp/contrived.pl:22 (frame 0).
$ warn $0
/tmp/contrived.pl at (eval 135) line 15, <FIN> line 1.
65. :t - Stack trace
:u - Up one stack frame
:d - Down one stack frame
:e - Print this frame's lexical environment
:q - Quit this REPL
$_e - ARRAYREF of this frame's @_
66. $ :t
0: Carp::REPL::repl called at /tmp/contrived.pl:22.
1: main::c called at /tmp/contrived.pl:15.
2: main::b called at /tmp/contrived.pl:9.
3: main::a called at /tmp/contrived.pl:27.
$
67. $ :e
$Env = { quot;$to_callquot; => do { my $v = 'does_not_exist' } };
$ :u
$ :u
Now at /tmp/contrived.pl:9 (frame 2).
$ :e
$Env = { quot;$to_callquot; => do { my $v = 'exist' } };
$ :u
Now at /tmp/contrived.pl:27 (frame 3).
$ :e
$Env = { quot;$to_callquot; => do { my $v = '' } };
$ :d
Now at /tmp/contrived.pl:9 (frame 2).
$ :e
$Env = { quot;$to_callquot; => do { my $v = 'exist' } };
$ warn join(quot;, quot;,@$_a);
exist at (eval 138) line 18, <FIN> line 4.
68. Why is my code 'warn'ing?
Maybe it's in an eval.
Or in a CPAN library.
No problem!
perl -MCarp::REPL=warn
69. 31b:~ jesse$ perl -MCarp::REPL=warn /tmp/contrived.pl
Use of uninitialized value in concatenation (.) or string at /tmp/contrived.pl
line 8.
0: Carp::REPL::repl called at /tmp/contrived.pl:8.
1: main::a called at /tmp/contrived.pl:27.
Now at /tmp/contrived.pl:8 (frame 0).
$ :e
$Env = { quot;$to_callquot; => do { my $v = undef } };
$ :q
Undefined subroutine &main::does_not_exist called at /tmp/contrived.pl line 22,
<FIN> line 2.
0: Carp::REPL::repl called at /tmp/contrived.pl:22.
1: main::c called at /tmp/contrived.pl:15.
2: main::b called at /tmp/contrived.pl:9.
3: main::a called at /tmp/contrived.pl:27.
Now at /tmp/contrived.pl:22 (frame 0).
$
70. Inserting breakpoints
You know your 'print' statements?
Turn them into breakpoints.
Two ways:
s/print/warn/ and -MCarp::REPL=warn
Carp::REPL::repl
71. 18.sub c {
19. my $to_call = shift;
20. no strict 'refs';
21. Carp::REPL::repl(); #Gimme a breakpoint here!
22. $to_call = quot;does_quot;.$to_call;
23. $to_call->();
24.}
72. What's next for
Carp::REPL?
I have no idea.
It's simple.
It works.
106. Tags as Closures
HTML tags take blocks of content
Our tag methods take blocks of Perl
They return closures when you want them
They run and output their content when you want them to
107. sub h1 (&;$) {
my $code = shift;
...
if (defined wantarray) {
return sub { ...closure around $code...};
} else {
# Actually do our work, run $code and
# return the output
return $code->();
}
}
108. What's next for
Template::Declare?
HTML Attribute Validation
Compile to .js
112. How CSS works
main.css:
@import quot;yui-fonts.cssquot;;
@import quot;base.cssquot;;
@import quot;layout.cssquot;;
@import quot;nav.cssquot;;
@import quot;forms.cssquot;;
@import quot;boxes.cssquot;;
@import quot;login.cssquot;;
...
113. How CSS works
⢠Browser downloads CSS stylesheets listed
in HTML
⢠Browser processes each stylesheet for
@include directives
⢠Browser fetches each stylesheet found
⢠This is slow.
114. How CSS works
To make CSS faster, you can tell browsers to cache stylesheets
...then you have trouble if you want to update your styles
Some people add datestamps to the stylesheet names:
/css/mypagestyle.css?1210362379
115. How CSS::Squish works
⢠It pretends to be a browser.
⢠You give it the path to a stylesheet.
⢠It returns the fully computed stylesheet the
browser would get eventually.
⢠You serve that ďŹle out to the user.
116. How we use
CSS::Squish
Instead of:
<link rel=quot;stylesheetquot; type=quot;text/cssquot;
href=quot;main.cssâ/>
We have this:
<link rel=quot;stylesheetquot; type=quot;text/cssquot; href=quot;/
css/squished/
4a50a85044a6ba727f7aa0683ac21f7e.cssâ/>
117. How we use
CSS::Squish
If we have a cached copy of the squished CSS, name the âďŹleâ as an
MD5 of the content
Tell browsers to cache it forever
When users load a page, they will always fetch the squished CSS if
itâs changed. By magic
118. Whatâs next for
CSS::Squish
Refactor the MD5 hash bits from Jifty to
CSS::Squish
What else do you want?
155. Shipwright and CPAN
CPAN-friendly
(Not CPAN-only)
CPAN dist import
Automatic CPAN dependency resolution
Full build ordering
No more CPAN dependency hell.
156. Shipwright and C
Native support for autoconďŹscated packages
No support for magic C->C dependency
resolutions
157. Shipwright and Ruby
Not Ruby friendly :(
(not Ruby unfriendly)
No Gem support yet
Hackathon this weekend?
158. What you can ship
A platform-neutral source distribution
Platform-speciďŹc binary distributions
159. Making a Shipwright
Vessel
svnadmin create file:///Users/jesse/shiprepo
shipwright create --repository
svn:file:///Users/jesse/shiprepo/myproject
shipwright import --repository
svn:file:///Users/jesse/shiprepo/myproject
cpan:Plagger
Go get a cup of coffee
(Shipwright will chase all 135 dependencies)
160. Building a Shipwright
Vessel
svn co file:///Users/jesse/shiprepo/myproject
cd myproject
./bin/shipwright-builder
(Possibly more coffee)
tar czvf myproject.tgz /path/to/build
161. Using a Shipwright
Vessel
⢠tar xzvf myproject.tgz c /usr/local/
myproject
⢠ln -s /usr/local/myproject/bin/myprogram
/usr/local/bin
162. What's next for
Shipwright?
Build tool usability improvements
Ruby support?
181. From: Jesse Vincent / Feedback <comment-373709-destygrypuju@tasks.hiveminder.com>
Date: Mon, 12 May 2008 12:31:49 -0700
Subject: Up for grabs: I'd really like Hiveminder to do all my work for me! (#EFYG)
Jesse Vincent <jesse@bestpractical.com> created a task and put it up for grabs:
http://task.hm/EFYG
I'd really like Hiveminder to do all my work for me!
--
Private debugging information:
Is a Pro user!
HTTP_ACCEPT: application/xml, text/xml, */*
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_ACCEPT_LANGUAGE: en-us
HTTP_CONNECTION: keep-alive
HTTP_COOKIE: JIFTY_SID_HIVEMINDER=b58e123456719fd411bb9f3a8123458f;
HTTP_HOST: hiveminder.com
HTTP_REFERER: http://hiveminder.com/todo/
HTTP_USER_AGENT: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_2; en-us)
AppleWebKit/526.5+ (KHTML, like Gecko) Version/3.1.1 Safari/525.18
HTTP_X_REQUESTED_WITH: XMLHttpRequest
REMOTE_ADDR: 75.147.59.54
REMOTE_PORT: 35412
REQUEST_METHOD: POST
REQUEST_URI: /todo/
202. package Demo::IMAP::Auth;
use base 'Net::IMAP::Server::DefaultAuth';
sub auth_plain {
my ($self, $user, $pass ) = @_;
# XXX DO AUTH CHECK
return 1;
}
203. package Demo::IMAP::Model;
use base 'Net::IMAP::Server::DefaultModel';
sub init {
my $self = shift;
$self->root(Demo::IMAP::Mailbox->new());
$self->root->add_child( name => quot;INBOXquot;,
is_inbox => 1);
}
204. package Demo::IMAP::Mailbox;
use base qw/Net::IMAP::Server::Mailbox/;
my $msg = Net::IMAP::Server::Message->new(<<'EOM');
From: jesse@example.com
To: user@example.com
Subject: This is a test message!
Hello. I am executive assistant to the director of
Bear Stearns, a failed investment Bank. I have
access to USD5,000,000. ...
EOM
sub load_data {
my $self = shift;
$self->add_message($msg);
}