diff options
author | Jesse Luehrs <doy@tozt.net> | 2018-10-13 02:17:44 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2018-10-13 02:37:01 -0400 |
commit | aa403b978860210fcbace7fcdf5830066f3e14e0 (patch) | |
tree | 0d8cf5a8855765ec2d83a865a12814d3b04454e7 /static | |
parent | ecd7793846441ba90b57140db19474f295f3e6d7 (diff) | |
download | tozt-hugo-aa403b978860210fcbace7fcdf5830066f3e14e0.tar.gz tozt-hugo-aa403b978860210fcbace7fcdf5830066f3e14e0.zip |
import site content
Diffstat (limited to 'static')
282 files changed, 15606 insertions, 0 deletions
diff --git a/static/blog/cartridge.jpg b/static/blog/cartridge.jpg Binary files differnew file mode 100644 index 0000000..e6d70ae --- /dev/null +++ b/static/blog/cartridge.jpg diff --git a/static/blog/input.s b/static/blog/input.s new file mode 100644 index 0000000..56ccee5 --- /dev/null +++ b/static/blog/input.s @@ -0,0 +1,135 @@ +.ROMBANKMAP +BANKSTOTAL 2 +BANKSIZE $4000 +BANKS 1 +BANKSIZE $2000 +BANKS 1 +.ENDRO + +.MEMORYMAP +DEFAULTSLOT 0 +SLOTSIZE $4000 +SLOT 0 $C000 +SLOTSIZE $2000 +SLOT 1 $0000 +.ENDME + +.ENUM $00 +sleeping DB +color DB +frame_count DB +.ENDE + + .bank 0 slot 0 + .org $0000 +RESET: + SEI + CLD + LDX #$FF + TXS + INX + STX $2000.w + STX $2001.w + STX $4010.w + LDX #$40 + STX $4017.w + +vblankwait1: + BIT $2002 + BPL vblankwait1 + +clrmem: + LDA #$00 + STA $0000, x + STA $0100, x + STA $0300, x + STA $0400, x + STA $0500, x + STA $0600, x + STA $0700, x + LDA #$FE + STA $0200, x + INX + BNE clrmem + + LDA #%10000001 + STA color + +vblankwait2: + BIT $2002 + BPL vblankwait2 + + LDA #%10000000 + STA $2000 + +loop: + INC sleeping +wait_for_vblank_end: + LDA sleeping + BNE wait_for_vblank_end + + ; controller 1 latch + LDA #$01 + STA $4016 + LDA #$00 + STA $4016 + + ; controller 1 clock, reading the state of the A button + LDA $4016 + AND #%00000001 + BNE change_color + JMP loop_end + ; reading the rest of the buttons is unnecessary, so we don't do it + +change_color: + LDA #$00 + STA frame_count + LDX color + CPX #%10000001 + BEQ turn_green + CPX #%01000001 + BEQ turn_red + +turn_blue: + LDA #%10000001 + STA color + JMP loop_end +turn_green: + LDA #%01000001 + STA color + JMP loop_end +turn_red: + LDA #%00100001 + STA color + +loop_end: + JMP loop + +NMI: + PHA + TXA + PHA + TYA + PHA + + LDA color + STA $2001 + + LDA #$00 + STA sleeping + PLA + TAY + PLA + TAX + PLA + + RTI + + .orga $FFFA + .dw NMI + .dw RESET + .dw 0 + + .bank 1 slot 1 + .org $0000 + .incbin "sprites.chr" diff --git a/static/blog/sprites.chr b/static/blog/sprites.chr Binary files differnew file mode 100644 index 0000000..3713c9c --- /dev/null +++ b/static/blog/sprites.chr diff --git a/static/blog/sprites.s b/static/blog/sprites.s new file mode 100644 index 0000000..5f0b3d9 --- /dev/null +++ b/static/blog/sprites.s @@ -0,0 +1,197 @@ +.ROMBANKMAP +BANKSTOTAL 2 +BANKSIZE $4000 +BANKS 1 +BANKSIZE $2000 +BANKS 1 +.ENDRO + +.MEMORYMAP +DEFAULTSLOT 0 +SLOTSIZE $4000 +SLOT 0 $C000 +SLOTSIZE $2000 +SLOT 1 $0000 +.ENDME + +.ENUM $00 +sleeping DB +.ENDE + +; just use the actual locations in our copy of SPR-RAM rather than zero-page +; addresses, to avoid having to do multiple copies +.define sprite_x $0203 +.define sprite_y $0200 + + .bank 0 slot 0 + .org $0000 +RESET: + SEI + CLD + LDX #$FF + TXS + INX + STX $2000.w + STX $2001.w + STX $4010.w + LDX #$40 + STX $4017.w + +vblankwait1: + BIT $2002 + BPL vblankwait1 + +clrmem: + LDA #$00 + STA $0000, x + STA $0100, x + STA $0300, x + STA $0400, x + STA $0500, x + STA $0600, x + STA $0700, x + LDA #$FE + STA $0200, x + INX + BNE clrmem + + ; start with the sprite near the middle of the screen + LDA #$80 + STA sprite_x + STA sprite_y + +vblankwait2: + BIT $2002 + BPL vblankwait2 + + ; PPU is initialized here, so we can start writing data into it. this is safe + ; because we have not yet enabled drawing, and so we don't have to restrain + ; ourselves to vblank. + + ; first, we load the palettes into $3F00 and $3F10 +load_palettes: + LDA $2002 ; read here so that the next byte written to $2006 is the high + LDA #$3F ; byte of the address + STA $2006 ; write the high byte of the base address + LDA #$00 + STA $2006 ; write the low byte of the base address + LDX #$00 +load_palettes_loop: + LDA palette.w, x + STA $2007 + INX + CPX #$20 ; 16 byte background palette plus 16 byte sprite palette + BNE load_palettes_loop + + ; then we draw the background (doing that here because it won't be changing) + LDA #$20 + STA $2006 ; high byte of the starting address + LDA #$00 + STA $2006 ; low byte of the starting address + LDA #$01 ; pattern index 1 is our background tile + LDX #$04 ; this loop will load $2000-$23FF, which includes the + LDY #$00 ; attribute table range, but we can just adjust the +load_background_loop: ; palette to take that into account + STA $2007 + INY + BNE load_background_loop + DEX + BNE load_background_loop + + ; then we set the unchanging parts of our sprite (the pattern index and the + ; attributes) + LDA #$00 + STA $0201 ; pattern index 0 is our sprite + STA $0202 ; don't need any attributes + + ; enable the PPU + LDA #%10000000 + STA $2000 + LDA #%00011000 + STA $2001 + +loop: + INC sleeping +wait_for_vblank_end: + LDA sleeping + BNE wait_for_vblank_end + + LDA #$01 + STA $4016 + LDA #$00 + STA $4016 + + ; we don't care about a, b, select, start + LDA $4016 + LDA $4016 + LDA $4016 + LDA $4016 + +up: + LDA $4016 + AND #%00000001 + BEQ down + LDX sprite_y.w + DEX + STX sprite_y.w +down: + LDA $4016 + AND #%00000001 + BEQ left + LDX sprite_y.w + INX + STX sprite_y.w +left: + LDA $4016 + AND #%00000001 + BEQ right + LDX sprite_x.w + DEX + STX sprite_x.w +right: + LDA $4016 + AND #%00000001 + BEQ loop_end + LDX sprite_x.w + INX + STX sprite_x.w + +loop_end: + JMP loop + +NMI: + PHA + TXA + PHA + TYA + PHA + + ; now the only thing we need to do here is issue a DMA call to transfer our + ; sprite data into SPR-RAM + LDA #$00 + STA $2003 ; reset the SPR-RAM write offset + LDA #$02 + STA $4014 ; start the DMA transfer from $0200 + + LDA #$00 + STA sleeping + PLA + TAY + PLA + TAX + PLA + + RTI + +palette: + .db $0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30 + .db $0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30,$0F,$30 + + .orga $FFFA + .dw NMI + .dw RESET + .dw 0 + + .bank 1 slot 1 + .org $0000 + .incbin "sprites.chr" diff --git a/static/talks/bread_board_yapc_eu_2012.key b/static/talks/bread_board_yapc_eu_2012.key Binary files differnew file mode 100644 index 0000000..d8e3a5f --- /dev/null +++ b/static/talks/bread_board_yapc_eu_2012.key diff --git a/static/talks/bread_board_yapc_eu_2012.pdf b/static/talks/bread_board_yapc_eu_2012.pdf Binary files differnew file mode 100644 index 0000000..22c82f8 --- /dev/null +++ b/static/talks/bread_board_yapc_eu_2012.pdf diff --git a/static/talks/bread_board_yapc_na_2012/001.html b/static/talks/bread_board_yapc_na_2012/001.html new file mode 100644 index 0000000..76f0738 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/001.html @@ -0,0 +1,51 @@ +<html> +<head> +<title>001</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependency Injection with Bread::Board + + Jesse Luehrs + Infinity Interactive + doy@cpan.org + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/002.html b/static/talks/bread_board_yapc_na_2012/002.html new file mode 100644 index 0000000..026d7d8 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/002.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>002</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "001" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "003.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + A Motivating Example + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/003.pl.html b/static/talks/bread_board_yapc_na_2012/003.pl.html new file mode 100644 index 0000000..d68c9c3 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/003.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>003.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "004.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + +package MyApp; +use MyFramework; + +sub call { + my $self = shift; + + my $dbh = DBI->connect('dbi:mysql:myapp_db'); + my $hello = $dbh->selectall_arrayref('SELECT * FROM my_table')->[0][0]; + + my $template = Template->new(INCLUDE_PATH => 'root/template'); + $template->process('hello.tt', { hello => $hello }, \(my $output)); + + return $output; +} + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/004.pl.html b/static/talks/bread_board_yapc_na_2012/004.pl.html new file mode 100644 index 0000000..83fba78 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/004.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>004.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "003.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + +package MyApp; +use MyFramework; + +has model => (is => 'ro', isa => 'Model', default => sub { Model->new }); +has view => (is => 'ro', isa => 'View', default => sub { View->new }); + +sub call { + my $self = shift; + my $hello = $self->model->get_hello; + return $self->view->render($hello); +} + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/005.pl.html b/static/talks/bread_board_yapc_na_2012/005.pl.html new file mode 100644 index 0000000..6475d93 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/005.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>005.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "004.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre>package MyApp; +use MyFramework; + +has logger => ( + is => 'ro', isa => 'Logger', + default => sub { Logger->new } +); +has model => ( + is => 'ro', isa => 'Model', lazy => 1, + default => sub { Model->new(logger => $_[0]->logger) }, +); +has view => ( + is => 'ro', isa => 'View', lazy => 1, + default => sub { View->new(logger => $_[0]->logger) }, +); + +sub call { + my $self = shift; + my $hello = $self->model->get_hello; + return $self->view->render($hello); +} + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/006.pl.html b/static/talks/bread_board_yapc_na_2012/006.pl.html new file mode 100644 index 0000000..593cc3e --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/006.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>006.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre>package MyApp; +use MyFramework; + +has dsn => (is => 'ro', isa => 'Str', default => 'dbi:mysql:myapp_db'); +has tt_root => (is => 'ro', isa => 'Str', default => 'root/template'); +has logger => (is => 'ro', isa => 'Logger', default => sub {Logger->new}); +has model => ( + is => 'ro', isa => 'Model', lazy => 1, + default => sub { + my $m = Model->connect($_[0]->dsn); + $m->set_logger($_[0]->logger); + return $m; + }, +); +has view => ( + is => 'ro', isa => 'View', lazy => 1, + default => sub { + View->new(logger => $_[0]->logger, tt_root => $_[0]->tt_root); + }, +); + +sub call { ... } + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/007.html b/static/talks/bread_board_yapc_na_2012/007.html new file mode 100644 index 0000000..44137e2 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/007.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>007</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependency Injection + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/007b.html b/static/talks/bread_board_yapc_na_2012/007b.html new file mode 100644 index 0000000..5388b4e --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/007b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>007b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependency Injection + + · a form of inversion of control + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/007c.html b/static/talks/bread_board_yapc_na_2012/007c.html new file mode 100644 index 0000000..2191491 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/007c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>007c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependency Injection + + · a form of inversion of control + · "the inverse of garbage collection" + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/007z.html b/static/talks/bread_board_yapc_na_2012/007z.html new file mode 100644 index 0000000..5656c3b --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/007z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>007z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependency Injection + + · a form of inversion of control + · "the inverse of garbage collection" + · manages object construction + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/008.html b/static/talks/bread_board_yapc_na_2012/008.html new file mode 100644 index 0000000..27b557b --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/008.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>008</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Benefits to Dependency Injection + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/008b.html b/static/talks/bread_board_yapc_na_2012/008b.html new file mode 100644 index 0000000..7cd24c5 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/008b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>008b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Benefits to Dependency Injection + + · provides access to the same object creation code + that your app will actually use + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/008c.html b/static/talks/bread_board_yapc_na_2012/008c.html new file mode 100644 index 0000000..ac32a8d --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/008c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>008c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Benefits to Dependency Injection + + · provides access to the same object creation code + that your app will actually use + · removes need for globals + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/008z.html b/static/talks/bread_board_yapc_na_2012/008z.html new file mode 100644 index 0000000..864c4b8 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/008z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>008z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Benefits to Dependency Injection + + · provides access to the same object creation code + that your app will actually use + · removes need for globals + · testing and reuse + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/009.html b/static/talks/bread_board_yapc_na_2012/009.html new file mode 100644 index 0000000..0a12b58 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/009.html @@ -0,0 +1,53 @@ +<html> +<head> +<title>009</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> Bread::Board + + + + + + + + + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/009z.html b/static/talks/bread_board_yapc_na_2012/009z.html new file mode 100644 index 0000000..0ace083 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/009z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>009z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> Bread::Board + + +-----------------------------------------+ + | A B C D E F G H I J | + |-----------------------------------------| + | o o | 1 o-o-o-o-o v o-o-o-o-o 1 | o o | + | o o | 2 o-o-o-o-o o-o-o-o-o 2 | o o | + | o o | 3 o-o-o-o-o o-o-o-o-o 3 | o o | + | o o | 4 o-o-o-o-o o-o-o-o-o 4 | o o | + | o o | 5 o-o-o-o-o o-o-o-o-o 5 | o o | + | | 6 o-o-o-o-o o-o-o-o-o 6 | | + | o o | 7 o-o-o-o-o o-o-o-o-o 7 | o o | + | o o | 8 o-o-o-o-o o-o-o-o-o 8 | o o | + | o o | 9 o-o-o-o-o o-o-o-o-o 9 | o o | + | o o | 10 o-o-o-o-o o-o-o-o-o 10 | o o | + | o o | 11 o-o-o-o-o o-o-o-o-o 11 | o o | + | | 12 o-o-o-o-o o-o-o-o-o 12 | | + | o o | 13 o-o-o-o-o o-o-o-o-o 13 | o o | + | o o | 14 o-o-o-o-o o-o-o-o-o 14 | o o | + | o o | 15 o-o-o-o-o o-o-o-o-o 15 | o o | + | o o | 16 o-o-o-o-o ^ o-o-o-o-o 16 | o o | + +-----------------------------------------+ + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/010.pl.html b/static/talks/bread_board_yapc_na_2012/010.pl.html new file mode 100644 index 0000000..35f1fa8 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/010.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>010.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> Bread::Board + +my $c = container MyApp => as { + service dsn => 'dbi:mysql:myapp_db'; + service logger => (class => 'Logger', lifecycle => 'Singleton'); + service view => (class => 'View', dependencies => ['logger']); + + service model => ( + class => 'Model', + dependencies => ['logger', 'dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, + ); + service app => ( + class => 'MyApp', + dependencies => ['model', 'view'], + ); +}; +$c->resolve(service => 'app'); + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/011.html b/static/talks/bread_board_yapc_na_2012/011.html new file mode 100644 index 0000000..27a352a --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/011.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>011</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Services + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/011b.html b/static/talks/bread_board_yapc_na_2012/011b.html new file mode 100644 index 0000000..0852e36 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/011b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>011b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Services + + · represent the data you're storing + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/011c.html b/static/talks/bread_board_yapc_na_2012/011c.html new file mode 100644 index 0000000..1acc353 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/011c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>011c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Services + + · represent the data you're storing + · access contents via the ->get method + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/011z.html b/static/talks/bread_board_yapc_na_2012/011z.html new file mode 100644 index 0000000..4c37ffc --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/011z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>011z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "012.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Services + + · represent the data you're storing + · access contents via the ->get method + · three built-in types: + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/012.pl.html b/static/talks/bread_board_yapc_na_2012/012.pl.html new file mode 100644 index 0000000..5fad51f --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/012.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>012.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "013.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::ConstructorInjection + + service view => ( + class => 'View', + ); + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/013.pl.html b/static/talks/bread_board_yapc_na_2012/013.pl.html new file mode 100644 index 0000000..6b70db8 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/013.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>013.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "012.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "014.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + Bread::Board::BlockInjection + + service model => ( + class => 'Model', # optional + block => sub { + my $m = Model->new + $m->initialize; + return $m; + }, + ); + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/014.pl.html b/static/talks/bread_board_yapc_na_2012/014.pl.html new file mode 100644 index 0000000..eb7c53d --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/014.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>014.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "013.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + Bread::Board::Literal + + service dsn => 'dbi:mysql:myapp_db'; + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/015.html b/static/talks/bread_board_yapc_na_2012/015.html new file mode 100644 index 0000000..f87c9e0 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/015.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>015</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "014.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Containers + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/015b.html b/static/talks/bread_board_yapc_na_2012/015b.html new file mode 100644 index 0000000..e02b3b9 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/015b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>015b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Containers + + · hold services and other containers + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/015c.html b/static/talks/bread_board_yapc_na_2012/015c.html new file mode 100644 index 0000000..e732750 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/015c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>015c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Containers + + · hold services and other containers + · access contents via the ->fetch method + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/015z.html b/static/talks/bread_board_yapc_na_2012/015z.html new file mode 100644 index 0000000..52bf73f --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/015z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>015z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Containers + + · hold services and other containers + · access contents via the ->fetch method + · ->resolve is a shortcut method for ->fetch(...)->get + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/016.html b/static/talks/bread_board_yapc_na_2012/016.html new file mode 100644 index 0000000..905afd9 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/016.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>016</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "016b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependencies + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/016b.html b/static/talks/bread_board_yapc_na_2012/016b.html new file mode 100644 index 0000000..8b0e0cd --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/016b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>016b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "016z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependencies + + · tells Bread::Board how your classes are related + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/016z.html b/static/talks/bread_board_yapc_na_2012/016z.html new file mode 100644 index 0000000..d9b1f4a --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/016z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>016z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "016b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "017.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Dependencies + + · tells Bread::Board how your classes are related + · specified as a map of names to service paths + (there are shortcuts for common cases) + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/017.pl.html b/static/talks/bread_board_yapc_na_2012/017.pl.html new file mode 100644 index 0000000..3490107 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/017.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>017.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "016z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "018.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + Dependencies + +service logger => (class => 'Logger'); +service view => ( + class => 'View', + dependencies => ['logger'], +); + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/018.pl.html b/static/talks/bread_board_yapc_na_2012/018.pl.html new file mode 100644 index 0000000..5de2fc0 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/018.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>018.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "017.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Dependencies + +service dsn => 'dbi:mysql:myapp_db'; +service model => ( + class => 'Model', + dependencies => ['dsn'], + block => sub { + my $service = shift; + return Model->connect($service->param('dsn')); + }, +); + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/019.pl.html b/static/talks/bread_board_yapc_na_2012/019.pl.html new file mode 100644 index 0000000..c9ee994 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/019.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>019.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "018.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + Dependencies + +container MyApp => as { + container Model => as { + service dsn => 'dbi:mysql:myapp_db'; + service model => ( + class => 'Model', + dependencies => ['dsn'], + block => sub { + my $service = shift; + return Model->connect($service->param('dsn')); + }, + ); + }; + service app => ( + class => 'MyApp', + dependencies => ['Model/model'], + ); +}; + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/020.html b/static/talks/bread_board_yapc_na_2012/020.html new file mode 100644 index 0000000..88b8442 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/020.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>020</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "020z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + Parameters + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/020z.html b/static/talks/bread_board_yapc_na_2012/020z.html new file mode 100644 index 0000000..2bc3569 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/020z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>020z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "021.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + Parameters + + · like dependencies, but supplied when calling ->get or ->resolve + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/021.pl.html b/static/talks/bread_board_yapc_na_2012/021.pl.html new file mode 100644 index 0000000..dcc1961 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/021.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>021.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "020z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); +}; +$c->resolve(service => 'user', parameters => { name => 'doy' }); + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/022.pl.html b/static/talks/bread_board_yapc_na_2012/022.pl.html new file mode 100644 index 0000000..d502072 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/022.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>022.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "021.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); + service superusers => ( + block => sub { [ $_[0]->param('root') ] }, + dependencies => { + root => { user => { name => 'root' } }, + }, + ); +}; + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/023.pl.html b/static/talks/bread_board_yapc_na_2012/023.pl.html new file mode 100644 index 0000000..f2c19f2 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/023.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>023.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); + service superusers => ( + block => sub { + [ $_[0]->param('user')->inflate(name => 'root') ] + }, + dependencies => ['user'], + ); +}; + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/024.pl.html b/static/talks/bread_board_yapc_na_2012/024.pl.html new file mode 100644 index 0000000..a780d22 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/024.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>024.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "025.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + Parameters + +my $c = container MyApp => as { + service default_username => 'guest'; + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str', optional => 1 }, + }, + dependencies => { + name => 'default_username', + }, + ); +}; +# user with name 'guest' +$c->resolve(service => 'user'); +# user with name 'doy' +$c->resolve(service => 'user', parameters => { name => 'doy' }); + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/025.pl.html b/static/talks/bread_board_yapc_na_2012/025.pl.html new file mode 100644 index 0000000..e39736f --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/025.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>025.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str', optional => 1, default => 'guest' }, + }, + ); +}; +# user with name 'guest' +$c->resolve(service => 'user'); +# user with name 'doy' +$c->resolve(service => 'user', parameters => { name => 'doy' }); + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/026.html b/static/talks/bread_board_yapc_na_2012/026.html new file mode 100644 index 0000000..5dbf9f2 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/026.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>026</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "025.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Lifecycles + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/026b.html b/static/talks/bread_board_yapc_na_2012/026b.html new file mode 100644 index 0000000..ca5f9e4 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/026b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>026b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Lifecycles + + · this is what determines what happens when ->get is called + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/026c.html b/static/talks/bread_board_yapc_na_2012/026c.html new file mode 100644 index 0000000..b1c28c9 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/026c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>026c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Lifecycles + + · this is what determines what happens when ->get is called + · by default, each call to ->get creates a new object + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/026z.html b/static/talks/bread_board_yapc_na_2012/026z.html new file mode 100644 index 0000000..925c234 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/026z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>026z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Lifecycles + + · this is what determines what happens when ->get is called + · by default, each call to ->get creates a new object + · by specifying «lifecycle => 'Singleton'» when creating the service, + the same object will be returned each time + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/027.pl.html b/static/talks/bread_board_yapc_na_2012/027.pl.html new file mode 100644 index 0000000..81900b4 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/027.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>027.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> Bread::Board + +my $c = container MyApp => as { + service dsn => 'dbi:mysql:myapp_db'; + service logger => (class => 'Logger', lifecycle => 'Singleton'); + service view => (class => 'View', dependencies => ['logger']); + + service model => ( + class => 'Model', + dependencies => ['logger', 'dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, + ); + service app => ( + class => 'MyApp', + dependencies => ['model', 'view'], + ); +}; +$c->resolve(service => 'app'); + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/028.html b/static/talks/bread_board_yapc_na_2012/028.html new file mode 100644 index 0000000..19f190a --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/028.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>028</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Best Practices + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/028b.html b/static/talks/bread_board_yapc_na_2012/028b.html new file mode 100644 index 0000000..5ad9534 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/028b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>028b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Best Practices + + · only use containers during initialization + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/028c.html b/static/talks/bread_board_yapc_na_2012/028c.html new file mode 100644 index 0000000..ea57d8e --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/028c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>028c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Best Practices + + · only use containers during initialization + · factories + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/028d.html b/static/talks/bread_board_yapc_na_2012/028d.html new file mode 100644 index 0000000..19c25bb --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/028d.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>028d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Best Practices + + · only use containers during initialization + · factories + · avoid unnecessary subcontainers + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/028z.html b/static/talks/bread_board_yapc_na_2012/028z.html new file mode 100644 index 0000000..b2977dd --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/028z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>028z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "029.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Best Practices + + · only use containers during initialization + · factories + · avoid unnecessary subcontainers + · container classes + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/029.pl.html b/static/talks/bread_board_yapc_na_2012/029.pl.html new file mode 100644 index 0000000..7422143 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/029.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>029.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + +package MyApp::Container; +use Moose; +extends 'Bread::Board::Container'; + +sub BUILD { + container $self => as { + ...; + }; +} + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/030.pl.html b/static/talks/bread_board_yapc_na_2012/030.pl.html new file mode 100644 index 0000000..185c53f --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/030.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>030.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "029.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + +container SomethingElse => as { + container MyApp::Container->new; +}; + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/031.html b/static/talks/bread_board_yapc_na_2012/031.html new file mode 100644 index 0000000..fb86ef0 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/031.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>031</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/031b.html b/static/talks/bread_board_yapc_na_2012/031b.html new file mode 100644 index 0000000..d2e173a --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/031b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>031b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + · defines a mapping from a class_type to a service + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/031c.html b/static/talks/bread_board_yapc_na_2012/031c.html new file mode 100644 index 0000000..af277de --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/031c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>031c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + · defines a mapping from a class_type to a service + · instead of requesting a particular service, you can request an + object of a particular type: $c->resolve(type => 'Model'); + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/031z.html b/static/talks/bread_board_yapc_na_2012/031z.html new file mode 100644 index 0000000..1e245f6 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/031z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>031z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "032.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + · defines a mapping from a class_type to a service + · instead of requesting a particular service, you can request an + object of a particular type: $c->resolve(type => 'Model'); + · with this, we can (mostly) infer the dependencies for a given class + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/032.pl.html b/static/talks/bread_board_yapc_na_2012/032.pl.html new file mode 100644 index 0000000..ec69e85 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/032.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>032.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "033.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + +package Model +use Moose; +has logger => (is => 'ro', isa => 'Logger', required => 1); + +package Logger; +use Moose; + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/033.pl.html b/static/talks/bread_board_yapc_na_2012/033.pl.html new file mode 100644 index 0000000..fe338d6 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/033.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>033.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "032.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + +my $c = container MyApp => as { + typemap Logger => infer; + typemap Model => infer; +}; +$c->resolve(type => 'Model')->logger; # a valid logger object + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/034.html b/static/talks/bread_board_yapc_na_2012/034.html new file mode 100644 index 0000000..7144e36 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/034.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>034</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "033.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "034b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/034b.html b/static/talks/bread_board_yapc_na_2012/034b.html new file mode 100644 index 0000000..fca66b8 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/034b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>034b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "034z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + · required attributes are automatically inferred, becoming either + dependencies (on types) or parameters (if the type doesn't exist + in the typemap) + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/034z.html b/static/talks/bread_board_yapc_na_2012/034z.html new file mode 100644 index 0000000..374ad23 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/034z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>034z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "034b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "035.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Typemaps + + · required attributes are automatically inferred, becoming either + dependencies (on types) or parameters (if the type doesn't exist + in the typemap) + · non-required attributes can still be satisfied by parameters + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/035.pl.html b/static/talks/bread_board_yapc_na_2012/035.pl.html new file mode 100644 index 0000000..944310b --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/035.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>035.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "034z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> Bread::Board::Declare + +package MyApp::Container; +use Moose; +use Bread::Board::Declare; + +has dsn => (is => 'ro', isa => 'Str', value => 'dbi:mysql:myapp_db'); +has logger => (is => 'ro', isa => 'Logger'); +has view => (is => 'ro', isa => 'View', infer => 1); + +has model => ( + is => 'ro', + isa => 'Model', + infer => 1, + dependencies => ['dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, +); +has app => (is => 'ro', isa => 'MyApp', infer => 1); + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/036.html b/static/talks/bread_board_yapc_na_2012/036.html new file mode 100644 index 0000000..a491785 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/036.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>036</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "035.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/036b.html b/static/talks/bread_board_yapc_na_2012/036b.html new file mode 100644 index 0000000..eb25288 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/036b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>036b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · services are declared just by defining attributes + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/036c.html b/static/talks/bread_board_yapc_na_2012/036c.html new file mode 100644 index 0000000..192c71c --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/036c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>036c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · services are declared just by defining attributes + · attribute accessors resolve the service if no value is set + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/036d.html b/static/talks/bread_board_yapc_na_2012/036d.html new file mode 100644 index 0000000..2b56f2d --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/036d.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>036d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · services are declared just by defining attributes + · attribute accessors resolve the service if no value is set + · if the attribute has a value, it is used in dependency resolution + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/036z.html b/static/talks/bread_board_yapc_na_2012/036z.html new file mode 100644 index 0000000..136d5ce --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/036z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>036z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · services are declared just by defining attributes + · attribute accessors resolve the service if no value is set + · if the attribute has a value, it is used in dependency resolution + · MyApp::Container->new(dsn => 'dbi:mysql:other_db')->model + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/037.html b/static/talks/bread_board_yapc_na_2012/037.html new file mode 100644 index 0000000..0868a72 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/037.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>037</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/037b.html b/static/talks/bread_board_yapc_na_2012/037b.html new file mode 100644 index 0000000..bd702a4 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/037b.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>037b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · typemaps are much simplified + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/037c.html b/static/talks/bread_board_yapc_na_2012/037c.html new file mode 100644 index 0000000..44d49f2 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/037c.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>037c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · typemaps are much simplified + · attributes with class_type constraints automatically get a typemap + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/037z.html b/static/talks/bread_board_yapc_na_2012/037z.html new file mode 100644 index 0000000..908bf38 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/037z.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>037z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "038.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Bread::Board::Declare + + · typemaps are much simplified + · attributes with class_type constraints automatically get a typemap + · «infer => 1» infers as many dependencies as possible + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/038.pl.html b/static/talks/bread_board_yapc_na_2012/038.pl.html new file mode 100644 index 0000000..8369221 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/038.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>038.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "039.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + MongoDBx::Bread::Board::Container + +container MyApp => as { + container MongoDBx::Bread::Board::Container->new( + name => 'myapp_db', + host => 'localhost', + database_layout => { + user_db => ['standard_users', 'super_users'], + }, + ); + + service authenticator => ( + class => 'Authenticator', + dependencies => ['myapp_db/user_db/standard_users'], + ); +}; + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/039.pl.html b/static/talks/bread_board_yapc_na_2012/039.pl.html new file mode 100644 index 0000000..9d19129 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/039.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>039.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "038.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "040.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + Catalyst::Plugin::Bread::Board + +package MyApp; +use Catalyst 'Bread::Board'; + +__PACKAGE__->config( + 'Plugin::Bread::Board' => { + container => MyApp::Container->new, + } +); + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/040.pl.html b/static/talks/bread_board_yapc_na_2012/040.pl.html new file mode 100644 index 0000000..5d846c5 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/040.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>040.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "039.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "041" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + OX + +package MyApp; +use OX; + +has model => (is => 'ro', isa => 'Model'); +has view => (is => 'ro', isa => 'View'); + +has controller => ( + is => 'ro', + isa => 'Controller', + infer => 1, +); + +router as { + route '/' => 'controller.index'; +}; + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/041.html b/static/talks/bread_board_yapc_na_2012/041.html new file mode 100644 index 0000000..a550e75 --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/041.html @@ -0,0 +1,48 @@ +<html> +<head> +<title>041</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "040.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + Questions? + + https://metacpan.org/module/Bread::Board + https://metacpan.org/module/Bread::Board::Declare + https://github.com/stevan/OX + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/index.html b/static/talks/bread_board_yapc_na_2012/index.html new file mode 100644 index 0000000..3247c2e --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/index.html @@ -0,0 +1,76 @@ +<html> +<head> +<title>Dependency Injection with Bread::Board</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 13 || keynum == 32) { + window.location = "001.html"; + return false; + } + return true; +} +</script> +<style> +body { + font-family: sans-serif; +} +h4 { + color: #888; +} +</style> +</head> +<body> +<h4>Use SPACEBAR to peruse the slides or click one to start...<h4> +<h1>Dependency Injection with Bread::Board</h1> +<ul> +<li><a href="001.html">Dependency Injection with Bread::Board</a></li> +<li><a href="002.html">A Motivating Example</a></li> +<li><a href="003.pl.html">package MyApp;</a></li> +<li><a href="004.pl.html">package MyApp;</a></li> +<li><a href="005.pl.html">package MyApp;</a></li> +<li><a href="006.pl.html">package MyApp;</a></li> +<li><a href="007.html">Dependency Injection</a></li> +<li><a href="008.html">Benefits to Dependency Injection</a></li> +<li><a href="009.html">Bread::Board</a></li> +<li><a href="010.pl.html">Bread::Board</a></li> +<li><a href="011.html">Services</a></li> +<li><a href="012.pl.html">Bread::Board::ConstructorInjection</a></li> +<li><a href="013.pl.html">Bread::Board::BlockInjection</a></li> +<li><a href="014.pl.html">Bread::Board::Literal</a></li> +<li><a href="015.html">Containers</a></li> +<li><a href="016.html">Dependencies</a></li> +<li><a href="017.pl.html">Dependencies</a></li> +<li><a href="018.pl.html">Dependencies</a></li> +<li><a href="019.pl.html">Dependencies</a></li> +<li><a href="020.html">Parameters</a></li> +<li><a href="021.pl.html">Parameters</a></li> +<li><a href="022.pl.html">Parameters</a></li> +<li><a href="023.pl.html">Parameters</a></li> +<li><a href="024.pl.html">Parameters</a></li> +<li><a href="025.pl.html">Parameters</a></li> +<li><a href="026.html">Lifecycles</a></li> +<li><a href="027.pl.html">Bread::Board</a></li> +<li><a href="028.html">Best Practices</a></li> +<li><a href="029.pl.html">package MyApp::Container;</a></li> +<li><a href="030.pl.html">container SomethingElse => as {</a></li> +<li><a href="031.html">Typemaps</a></li> +<li><a href="032.pl.html">package Model</a></li> +<li><a href="033.pl.html">my $c = container MyApp => as {</a></li> +<li><a href="034.html">Typemaps</a></li> +<li><a href="035.pl.html">Bread::Board::Declare</a></li> +<li><a href="036.html">Bread::Board::Declare</a></li> +<li><a href="037.html">Bread::Board::Declare</a></li> +<li><a href="038.pl.html">MongoDBx::Bread::Board::Container</a></li> +<li><a href="039.pl.html">Catalyst::Plugin::Bread::Board</a></li> +<li><a href="040.pl.html">OX</a></li> +<li><a href="041.html">Questions?</a></li> +</ul> +<p>This presentation was generated by <a +href="http://ingydotnet.github.com/vroom-pm">Vroom</a>. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +</p> +</body> diff --git a/static/talks/bread_board_yapc_na_2012/slides.vroom b/static/talks/bread_board_yapc_na_2012/slides.vroom new file mode 100644 index 0000000..404431f --- /dev/null +++ b/static/talks/bread_board_yapc_na_2012/slides.vroom @@ -0,0 +1,508 @@ +# urxvt -fg black -bg white +# setfont 'xft:DejaVuSansMono-19:bold' +# echo 'set exrc' >> ~/.vimrc + +---- config +title: Dependency Injection with Bread::Board +indent: 4 +auto_size: 1 + +---- center +Dependency Injection with Bread::Board + +Jesse Luehrs +Infinity Interactive +doy@cpan.org +---- +== A Motivating Example +---- perl,i0 +package MyApp; +use MyFramework; + +sub call { + my $self = shift; + + my $dbh = DBI->connect('dbi:mysql:myapp_db'); + my $hello = $dbh->selectall_arrayref('SELECT * FROM my_table')->[0][0]; + + my $template = Template->new(INCLUDE_PATH => 'root/template'); + $template->process('hello.tt', { hello => $hello }, \(my $output)); + + return $output; +} +---- perl,i0 +package MyApp; +use MyFramework; + +has model => (is => 'ro', isa => 'Model', default => sub { Model->new }); +has view => (is => 'ro', isa => 'View', default => sub { View->new }); + +sub call { + my $self = shift; + my $hello = $self->model->get_hello; + return $self->view->render($hello); +} +---- perl,i0 +package MyApp; +use MyFramework; + +has logger => ( + is => 'ro', isa => 'Logger', + default => sub { Logger->new } +); +has model => ( + is => 'ro', isa => 'Model', lazy => 1, + default => sub { Model->new(logger => $_[0]->logger) }, +); +has view => ( + is => 'ro', isa => 'View', lazy => 1, + default => sub { View->new(logger => $_[0]->logger) }, +); + +sub call { + my $self = shift; + my $hello = $self->model->get_hello; + return $self->view->render($hello); +} +---- perl,i0 +package MyApp; +use MyFramework; + +has dsn => (is => 'ro', isa => 'Str', default => 'dbi:mysql:myapp_db'); +has tt_root => (is => 'ro', isa => 'Str', default => 'root/template'); +has logger => (is => 'ro', isa => 'Logger', default => sub {Logger->new}); +has model => ( + is => 'ro', isa => 'Model', lazy => 1, + default => sub { + my $m = Model->connect($_[0]->dsn); + $m->set_logger($_[0]->logger); + return $m; + }, +); +has view => ( + is => 'ro', isa => 'View', lazy => 1, + default => sub { + View->new(logger => $_[0]->logger, tt_root => $_[0]->tt_root); + }, +); + +sub call { ... } +---- +Dependency Injection + ++ · a form of inversion of control ++ · "the inverse of garbage collection" ++ · manages object construction +---- +Benefits to Dependency Injection + ++ · provides access to the same object creation code + that your app will actually use ++ · removes need for globals ++ · testing and reuse +---- center,-i1 +== Bread::Board + ++ +-----------------------------------------+ + | A B C D E F G H I J | + |-----------------------------------------| + | o o | 1 o-o-o-o-o v o-o-o-o-o 1 | o o | + | o o | 2 o-o-o-o-o o-o-o-o-o 2 | o o | + | o o | 3 o-o-o-o-o o-o-o-o-o 3 | o o | + | o o | 4 o-o-o-o-o o-o-o-o-o 4 | o o | + | o o | 5 o-o-o-o-o o-o-o-o-o 5 | o o | + | | 6 o-o-o-o-o o-o-o-o-o 6 | | + | o o | 7 o-o-o-o-o o-o-o-o-o 7 | o o | + | o o | 8 o-o-o-o-o o-o-o-o-o 8 | o o | + | o o | 9 o-o-o-o-o o-o-o-o-o 9 | o o | + | o o | 10 o-o-o-o-o o-o-o-o-o 10 | o o | + | o o | 11 o-o-o-o-o o-o-o-o-o 11 | o o | + | | 12 o-o-o-o-o o-o-o-o-o 12 | | + | o o | 13 o-o-o-o-o o-o-o-o-o 13 | o o | + | o o | 14 o-o-o-o-o o-o-o-o-o 14 | o o | + | o o | 15 o-o-o-o-o o-o-o-o-o 15 | o o | + | o o | 16 o-o-o-o-o ^ o-o-o-o-o 16 | o o | + +-----------------------------------------+ +---- perl,i0 +== Bread::Board + +my $c = container MyApp => as { + service dsn => 'dbi:mysql:myapp_db'; + service logger => (class => 'Logger', lifecycle => 'Singleton'); + service view => (class => 'View', dependencies => ['logger']); + + service model => ( + class => 'Model', + dependencies => ['logger', 'dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, + ); + service app => ( + class => 'MyApp', + dependencies => ['model', 'view'], + ); +}; +$c->resolve(service => 'app'); +---- +== Services + ++ · represent the data you're storing ++ · access contents via the ->get method ++ · three built-in types: +---- perl +== Bread::Board::ConstructorInjection + +service view => ( + class => 'View', +); +---- perl +== Bread::Board::BlockInjection + +service model => ( + class => 'Model', # optional + block => sub { + my $m = Model->new + $m->initialize; + return $m; + }, +); +---- perl +== Bread::Board::Literal + +service dsn => 'dbi:mysql:myapp_db'; +---- +== Containers + ++ · hold services and other containers ++ · access contents via the ->fetch method ++ · ->resolve is a shortcut method for ->fetch(...)->get +---- +== Dependencies + ++ · tells Bread::Board how your classes are related ++ · specified as a map of names to service paths + (there are shortcuts for common cases) +---- perl,i0 +== Dependencies + +service logger => (class => 'Logger'); +service view => ( + class => 'View', + dependencies => ['logger'], +); +---- perl,i0 +== Dependencies + +service dsn => 'dbi:mysql:myapp_db'; +service model => ( + class => 'Model', + dependencies => ['dsn'], + block => sub { + my $service = shift; + return Model->connect($service->param('dsn')); + }, +); +---- perl,i0 +== Dependencies + +container MyApp => as { + container Model => as { + service dsn => 'dbi:mysql:myapp_db'; + service model => ( + class => 'Model', + dependencies => ['dsn'], + block => sub { + my $service = shift; + return Model->connect($service->param('dsn')); + }, + ); + }; + service app => ( + class => 'MyApp', + dependencies => ['Model/model'], + ); +}; +---- +== Parameters + ++ · like dependencies, but supplied when calling ->get or ->resolve +---- perl,i0 +== Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); +}; +$c->resolve(service => 'user', parameters => { name => 'doy' }); +---- perl,i0 +== Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); + service superusers => ( + block => sub { [ $_[0]->param('root') ] }, + dependencies => { + root => { user => { name => 'root' } }, + }, + ); +}; +---- perl,i0 +== Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str' }, + }, + ); + service superusers => ( + block => sub { + [ $_[0]->param('user')->inflate(name => 'root') ] + }, + dependencies => ['user'], + ); +}; +---- perl,i0 +== Parameters + +my $c = container MyApp => as { + service default_username => 'guest'; + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str', optional => 1 }, + }, + dependencies => { + name => 'default_username', + }, + ); +}; +# user with name 'guest' +$c->resolve(service => 'user'); +# user with name 'doy' +$c->resolve(service => 'user', parameters => { name => 'doy' }); +---- perl,i0 +== Parameters + +my $c = container MyApp => as { + service user => ( + class => 'User', + parameters => { + name => { isa => 'Str', optional => 1, default => 'guest' }, + }, + ); +}; +# user with name 'guest' +$c->resolve(service => 'user'); +# user with name 'doy' +$c->resolve(service => 'user', parameters => { name => 'doy' }); +---- +== Lifecycles + ++ · this is what determines what happens when ->get is called ++ · by default, each call to ->get creates a new object ++ · by specifying «lifecycle => 'Singleton'» when creating the service, + the same object will be returned each time +---- perl,i0 +== Bread::Board + +my $c = container MyApp => as { + service dsn => 'dbi:mysql:myapp_db'; + service logger => (class => 'Logger', lifecycle => 'Singleton'); + service view => (class => 'View', dependencies => ['logger']); + + service model => ( + class => 'Model', + dependencies => ['logger', 'dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, + ); + service app => ( + class => 'MyApp', + dependencies => ['model', 'view'], + ); +}; +$c->resolve(service => 'app'); +---- +== Best Practices + ++ · only use containers during initialization ++ · factories ++ · avoid unnecessary subcontainers ++ · container classes +---- perl,i0 +package MyApp::Container; +use Moose; +extends 'Bread::Board::Container'; + +sub BUILD { + container $self => as { + ...; + }; +} +---- perl,i0 +container SomethingElse => as { + container MyApp::Container->new; +}; +---- +== Typemaps + ++ · defines a mapping from a class_type to a service ++ · instead of requesting a particular service, you can request an + object of a particular type: $c->resolve(type => 'Model'); ++ · with this, we can (mostly) infer the dependencies for a given class +---- perl,i0 +package Model +use Moose; +has logger => (is => 'ro', isa => 'Logger', required => 1); + +package Logger; +use Moose; +---- perl,i0 +my $c = container MyApp => as { + typemap Logger => infer; + typemap Model => infer; +}; +$c->resolve(type => 'Model')->logger; # a valid logger object +---- +== Typemaps + ++ · required attributes are automatically inferred, becoming either + dependencies (on types) or parameters (if the type doesn't exist + in the typemap) ++ · non-required attributes can still be satisfied by parameters +---- perl,i0 +== Bread::Board::Declare + +package MyApp::Container; +use Moose; +use Bread::Board::Declare; + +has dsn => (is => 'ro', isa => 'Str', value => 'dbi:mysql:myapp_db'); +has logger => (is => 'ro', isa => 'Logger'); +has view => (is => 'ro', isa => 'View', infer => 1); + +has model => ( + is => 'ro', + isa => 'Model', + infer => 1, + dependencies => ['dsn'], + block => sub { + my $m = Model->connect($_[0]->param('dsn')); + $m->set_logger($_[0]->param('logger')); + return $m; + }, +); +has app => (is => 'ro', isa => 'MyApp', infer => 1); +---- +== Bread::Board::Declare + ++ · services are declared just by defining attributes ++ · attribute accessors resolve the service if no value is set ++ · if the attribute has a value, it is used in dependency resolution ++ · MyApp::Container->new(dsn => 'dbi:mysql:other_db')->model +---- +== Bread::Board::Declare + ++ · typemaps are much simplified ++ · attributes with class_type constraints automatically get a typemap ++ · «infer => 1» infers as many dependencies as possible +---- perl,i0 +== MongoDBx::Bread::Board::Container + +container MyApp => as { + container MongoDBx::Bread::Board::Container->new( + name => 'myapp_db', + host => 'localhost', + database_layout => { + user_db => ['standard_users', 'super_users'], + }, + ); + + service authenticator => ( + class => 'Authenticator', + dependencies => ['myapp_db/user_db/standard_users'], + ); +}; +---- perl,i0 +== Catalyst::Plugin::Bread::Board + +package MyApp; +use Catalyst 'Bread::Board'; + +__PACKAGE__->config( + 'Plugin::Bread::Board' => { + container => MyApp::Container->new, + } +); + +---- perl,i0 +== OX + +package MyApp; +use OX; + +has model => (is => 'ro', isa => 'Model'); +has view => (is => 'ro', isa => 'View'); + +has controller => ( + is => 'ro', + isa => 'Controller', + infer => 1, +); + +router as { + route '/' => 'controller.index'; +}; + +---- center +Questions? + +https://metacpan.org/module/Bread::Board +https://metacpan.org/module/Bread::Board::Declare +https://github.com/stevan/OX +---- skip +motivating example (5m, 5s) +- everything inline +- separate model/view classes +- model and view classes both want a logger +- model and logger both want configuration +overview of dependency injection (5m, 1s) +- high level description +- ...??? +bread::board (15m, 4s) +- simple example (translation of intro?) +- services and containers +- dependencies, parameters +- lifecycles +- typemaps +- best practices + - not global - factory classes/closures, etc + - container classes +bread::board::declare (10m) +- show example +- attributes are services are attributes +- automatic typemapping +- subclassing, roles +- subcontainers +real world usage (10m) +- bread::board::container::mongodb +- catalyst::plugin::bread::board +- ox +questions (5m) diff --git a/static/talks/extending_moose_yapc_na_2010/001.html b/static/talks/extending_moose_yapc_na_2010/001.html new file mode 100644 index 0000000..c31f6fb --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/001.html @@ -0,0 +1,45 @@ +<html> +<head> +<title>001</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + Extending Moose + + by Jesse Luehrs (doy at tozt dot net) + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/002.html b/static/talks/extending_moose_yapc_na_2010/002.html new file mode 100644 index 0000000..f19d2f4 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/002.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>002</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "001" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "003" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + motivation + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/003.html b/static/talks/extending_moose_yapc_na_2010/003.html new file mode 100644 index 0000000..190d180 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/003.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>003</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "003b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/003b.html b/static/talks/extending_moose_yapc_na_2010/003b.html new file mode 100644 index 0000000..a9b584a --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/003b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>003b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "003" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "003z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose + + great class builder + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/003z.html b/static/talks/extending_moose_yapc_na_2010/003z.html new file mode 100644 index 0000000..af6fdcf --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/003z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>003z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "003b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "004" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose + + great class builder + + lots of beginner info available + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/004.html b/static/talks/extending_moose_yapc_na_2010/004.html new file mode 100644 index 0000000..2bd886a --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/004.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>004</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "003z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + using only the basic features doesn't gain you much + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/005.pl.html b/static/talks/extending_moose_yapc_na_2010/005.pl.html new file mode 100644 index 0000000..7a80895 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/005.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>005.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "004" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + package Foo; + use base qw(Class::Accessor); + __PACKAGE__->mk_accessors('bar'); + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/006.pl.html b/static/talks/extending_moose_yapc_na_2010/006.pl.html new file mode 100644 index 0000000..4827510 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/006.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>006.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + package Foo; + use Moose; + has bar => (is => 'ro'); + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/007.pl.html b/static/talks/extending_moose_yapc_na_2010/007.pl.html new file mode 100644 index 0000000..4867c18 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/007.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>007.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007z.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + but... + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/007z.pl.html b/static/talks/extending_moose_yapc_na_2010/007z.pl.html new file mode 100644 index 0000000..4f05317 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/007z.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>007z.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + but... + + package Foo; + use Class::Accessor 'antlers'; + has bar => (is => 'ro'); + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/008.html b/static/talks/extending_moose_yapc_na_2010/008.html new file mode 100644 index 0000000..3d6357b --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/008.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>008</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007z.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose gives you more than this + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/008b.html b/static/talks/extending_moose_yapc_na_2010/008b.html new file mode 100644 index 0000000..2770f7d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/008b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>008b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose gives you more than this + + * builders + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/008c.html b/static/talks/extending_moose_yapc_na_2010/008c.html new file mode 100644 index 0000000..b4b5ae0 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/008c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>008c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose gives you more than this + + * builders + * delegation + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/008d.html b/static/talks/extending_moose_yapc_na_2010/008d.html new file mode 100644 index 0000000..68d9c4d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/008d.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>008d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose gives you more than this + + * builders + * delegation + * roles + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/008z.html b/static/talks/extending_moose_yapc_na_2010/008z.html new file mode 100644 index 0000000..3e990be --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/008z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>008z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + moose gives you more than this + + * builders + * delegation + * roles + * etc... + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/009.html b/static/talks/extending_moose_yapc_na_2010/009.html new file mode 100644 index 0000000..465baf3 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/009.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>009</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + but the real power of moose is in extensibility + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/010.html b/static/talks/extending_moose_yapc_na_2010/010.html new file mode 100644 index 0000000..7efb1f3 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/010.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>010</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + typical object systems are defined in terms of, well, object systems + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/010b.html b/static/talks/extending_moose_yapc_na_2010/010b.html new file mode 100644 index 0000000..e997ca4 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/010b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>010b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + typical object systems are defined in terms of, well, object systems + + has input_file => ( + is => 'ro', + isa => File, + coerce => 1, + required => 1, + ); + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/010c.html b/static/talks/extending_moose_yapc_na_2010/010c.html new file mode 100644 index 0000000..c91a322 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/010c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>010c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + typical object systems are defined in terms of, well, object systems + + has input_file => ( + is => 'ro', + isa => File, + coerce => 1, + required => 1, + ); + + wouldn't it be nice to be able to say what we mean? + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/010z.html b/static/talks/extending_moose_yapc_na_2010/010z.html new file mode 100644 index 0000000..b2c5610 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/010z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>010z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + typical object systems are defined in terms of, well, object systems + + has input_file => ( + is => 'ro', + isa => File, + coerce => 1, + required => 1, + ); + + wouldn't it be nice to be able to say what we mean? + + has_file 'input_file'; + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/011.html b/static/talks/extending_moose_yapc_na_2010/011.html new file mode 100644 index 0000000..1b0effd --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/011.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>011</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + code should be written with the intent of communicating with *humans* + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/011b.html b/static/talks/extending_moose_yapc_na_2010/011b.html new file mode 100644 index 0000000..4d7ab4e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/011b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>011b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + code should be written with the intent of communicating with *humans* + + computers are great at figuring out the details on their own + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/011z.html b/static/talks/extending_moose_yapc_na_2010/011z.html new file mode 100644 index 0000000..f7a00ff --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/011z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>011z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "012" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + code should be written with the intent of communicating with *humans* + + computers are great at figuring out the details on their own + + write code in the language of the domain rather than the language of the computer + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/012.html b/static/talks/extending_moose_yapc_na_2010/012.html new file mode 100644 index 0000000..654ab11 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/012.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>012</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "013" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + this has different levels: + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/013.html b/static/talks/extending_moose_yapc_na_2010/013.html new file mode 100644 index 0000000..4d28940 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/013.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>013</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "012" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "014" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + perl: + + a user is a hash table with a key storing the username and a key storing the password, associated with a set of functions for manipulating those hash keys while validating them and ensuring they remain consistent + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/014.html b/static/talks/extending_moose_yapc_na_2010/014.html new file mode 100644 index 0000000..663661d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/014.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>014</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "013" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + moose (by default): + + a user has a readonly string attribute storing the username, and a read/write Authen::Passphrase object storing the password, which password checking is delegated to + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/015.html b/static/talks/extending_moose_yapc_na_2010/015.html new file mode 100644 index 0000000..4e43d87 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/015.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>015</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "014" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + but what we'd really like is: + + a user has a name, and you can ask if its password is correct + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/016.html b/static/talks/extending_moose_yapc_na_2010/016.html new file mode 100644 index 0000000..c43d2b9 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/016.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>016</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "017" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + moose can give us this too + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/017.html b/static/talks/extending_moose_yapc_na_2010/017.html new file mode 100644 index 0000000..f99d50c --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/017.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>017</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "017z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + the mop + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/017z.html b/static/talks/extending_moose_yapc_na_2010/017z.html new file mode 100644 index 0000000..3a57d5c --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/017z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>017z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "017" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "018" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + the mop + + (meta object protocol) + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/018.html b/static/talks/extending_moose_yapc_na_2010/018.html new file mode 100644 index 0000000..90604ea --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/018.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>018</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "017z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + models classes as objects + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/019.html b/static/talks/extending_moose_yapc_na_2010/019.html new file mode 100644 index 0000000..a554692 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/019.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>019</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "018" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + every class is represented by a metaclass + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/019b.html b/static/talks/extending_moose_yapc_na_2010/019b.html new file mode 100644 index 0000000..f988661 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/019b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>019b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + every class is represented by a metaclass + + a normal perl object of the class Moose::Meta::Class + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/019c.html b/static/talks/extending_moose_yapc_na_2010/019c.html new file mode 100644 index 0000000..d1a9e60 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/019c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>019c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + every class is represented by a metaclass + + a normal perl object of the class Moose::Meta::Class + + contains attributes and methods as members (objects of Moose::Meta::Attribute and Moose::Meta::Method) + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/019z.html b/static/talks/extending_moose_yapc_na_2010/019z.html new file mode 100644 index 0000000..e894c8f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/019z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>019z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + every class is represented by a metaclass + + a normal perl object of the class Moose::Meta::Class + + contains attributes and methods as members (objects of Moose::Meta::Attribute and Moose::Meta::Method) + + (other stuff too, but we'll ignore that for now) + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/020.html b/static/talks/extending_moose_yapc_na_2010/020.html new file mode 100644 index 0000000..62ad473 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/020.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>020</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "021" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + Moose::Meta::Class + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/021.html b/static/talks/extending_moose_yapc_na_2010/021.html new file mode 100644 index 0000000..32f72bc --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/021.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>021</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + access these objects through Class->meta (a class method installed by "use Moose") + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/022.html b/static/talks/extending_moose_yapc_na_2010/022.html new file mode 100644 index 0000000..457936d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/022.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>022</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "021" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + class information is stored and manipulated through these objects + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/022b.html b/static/talks/extending_moose_yapc_na_2010/022b.html new file mode 100644 index 0000000..45d26f7 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/022b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>022b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + class information is stored and manipulated through these objects + + * "@ISA = ('Foo')" -> "$meta->superclasses('Foo')" + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/022c.html b/static/talks/extending_moose_yapc_na_2010/022c.html new file mode 100644 index 0000000..10aa7d5 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/022c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>022c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + class information is stored and manipulated through these objects + + * "@ISA = ('Foo')" -> "$meta->superclasses('Foo')" + * "*foo = sub { ... }" -> "$meta->add_method(foo => sub { ... })" + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/022z.html b/static/talks/extending_moose_yapc_na_2010/022z.html new file mode 100644 index 0000000..66ad3f2 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/022z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>022z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + class information is stored and manipulated through these objects + + * "@ISA = ('Foo')" -> "$meta->superclasses('Foo')" + * "*foo = sub { ... }" -> "$meta->add_method(foo => sub { ... })" + * "our $foo = 'bar'" -> "$meta->add_package_symbol('$foo' => 'bar')" + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/023.html b/static/talks/extending_moose_yapc_na_2010/023.html new file mode 100644 index 0000000..40a7d40 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/023.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>023</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + also provides informational methods + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/023b.html b/static/talks/extending_moose_yapc_na_2010/023b.html new file mode 100644 index 0000000..80a061f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/023b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>023b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + also provides informational methods + + * $meta->class_precedence_list + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/023c.html b/static/talks/extending_moose_yapc_na_2010/023c.html new file mode 100644 index 0000000..cc76ea1 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/023c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>023c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + also provides informational methods + + * $meta->class_precedence_list + * $meta->has_method('foo') + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/023z.html b/static/talks/extending_moose_yapc_na_2010/023z.html new file mode 100644 index 0000000..15e1a9f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/023z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>023z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + also provides informational methods + + * $meta->class_precedence_list + * $meta->has_method('foo') + * $meta->does_role('Role') + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/024.html b/static/talks/extending_moose_yapc_na_2010/024.html new file mode 100644 index 0000000..dfe10cf --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/024.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>024</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + and provides other functionality specific to the mop + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/024b.html b/static/talks/extending_moose_yapc_na_2010/024b.html new file mode 100644 index 0000000..bc9e7eb --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/024b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>024b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + and provides other functionality specific to the mop + + * $meta->make_immutable + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/024c.html b/static/talks/extending_moose_yapc_na_2010/024c.html new file mode 100644 index 0000000..eff147a --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/024c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>024c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + and provides other functionality specific to the mop + + * $meta->make_immutable + * $meta->new_object + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/024z.html b/static/talks/extending_moose_yapc_na_2010/024z.html new file mode 100644 index 0000000..4377e46 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/024z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>024z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "025" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + and provides other functionality specific to the mop + + * $meta->make_immutable + * $meta->new_object + * Moose::Meta::Class->create_anon_class + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/025.html b/static/talks/extending_moose_yapc_na_2010/025.html new file mode 100644 index 0000000..8c0fb47 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/025.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>025</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + Moose::Meta::Attribute + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/026.html b/static/talks/extending_moose_yapc_na_2010/026.html new file mode 100644 index 0000000..de53cf0 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/026.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>026</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "025" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + accessed through $meta->get_attribute, etc + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/026b.html b/static/talks/extending_moose_yapc_na_2010/026b.html new file mode 100644 index 0000000..f17a95d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/026b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>026b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + accessed through $meta->get_attribute, etc + + stores data associated with an object + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/026z.html b/static/talks/extending_moose_yapc_na_2010/026z.html new file mode 100644 index 0000000..333da3d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/026z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>026z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + accessed through $meta->get_attribute, etc + + stores data associated with an object + + also handles installing methods associated with accessing that data + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/027.html b/static/talks/extending_moose_yapc_na_2010/027.html new file mode 100644 index 0000000..c005bdb --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/027.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>027</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + informational methods: + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/027b.html b/static/talks/extending_moose_yapc_na_2010/027b.html new file mode 100644 index 0000000..70ac8e8 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/027b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>027b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + informational methods: + + * $meta_attr->get_read_method + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/027z.html b/static/talks/extending_moose_yapc_na_2010/027z.html new file mode 100644 index 0000000..ecd850c --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/027z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>027z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + informational methods: + + * $meta_attr->get_read_method + * $meta_attr->type_constraint + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/028.html b/static/talks/extending_moose_yapc_na_2010/028.html new file mode 100644 index 0000000..7c3bbc4 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/028.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>028</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + accessing data handled by the attribute + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/028z.html b/static/talks/extending_moose_yapc_na_2010/028z.html new file mode 100644 index 0000000..f39c97b --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/028z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>028z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "029" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + accessing data handled by the attribute + + $meta_attr->get_value($obj) + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/029.html b/static/talks/extending_moose_yapc_na_2010/029.html new file mode 100644 index 0000000..b938d34 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/029.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>029</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + Moose::Meta::Method + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/030.html b/static/talks/extending_moose_yapc_na_2010/030.html new file mode 100644 index 0000000..b864827 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/030.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>030</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "029" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + accessed through $meta->get_method, etc + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/030b.html b/static/talks/extending_moose_yapc_na_2010/030b.html new file mode 100644 index 0000000..9863b08 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/030b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>030b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + accessed through $meta->get_method, etc + + represents a method associated with a class + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/030c.html b/static/talks/extending_moose_yapc_na_2010/030c.html new file mode 100644 index 0000000..194dce3 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/030c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>030c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + accessed through $meta->get_method, etc + + represents a method associated with a class + + these are typically introspected from the symbol table, not created explicitly + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/030z.html b/static/talks/extending_moose_yapc_na_2010/030z.html new file mode 100644 index 0000000..f22650e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/030z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>030z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + accessed through $meta->get_method, etc + + represents a method associated with a class + + these are typically introspected from the symbol table, not created explicitly + + they can be created explicitly if necessary; this is how method modifiers work + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/031.html b/static/talks/extending_moose_yapc_na_2010/031.html new file mode 100644 index 0000000..35c8df2 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/031.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>031</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "032" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + so how does this all work? + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/032.html b/static/talks/extending_moose_yapc_na_2010/032.html new file mode 100644 index 0000000..2397bac --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/032.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>032</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "033" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + metacircularity + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/033.html b/static/talks/extending_moose_yapc_na_2010/033.html new file mode 100644 index 0000000..19058b2 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/033.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>033</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "032" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "033b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + metaclasses are instances of the class Moose::Meta::Class + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/033b.html b/static/talks/extending_moose_yapc_na_2010/033b.html new file mode 100644 index 0000000..2b0905d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/033b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>033b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "033" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "033z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + metaclasses are instances of the class Moose::Meta::Class + + but Moose::Meta::Class is itself a class + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/033z.html b/static/talks/extending_moose_yapc_na_2010/033z.html new file mode 100644 index 0000000..41d5355 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/033z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>033z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "033b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + metaclasses are instances of the class Moose::Meta::Class + + but Moose::Meta::Class is itself a class + + so it must have a metaclass + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/034.html b/static/talks/extending_moose_yapc_na_2010/034.html new file mode 100644 index 0000000..a7c2160 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/034.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>034</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "033z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "035" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + this is accomplished by two tricks + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/035.html b/static/talks/extending_moose_yapc_na_2010/035.html new file mode 100644 index 0000000..2cdfecb --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/035.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>035</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "035z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + compiler bootstrapping + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/035z.html b/static/talks/extending_moose_yapc_na_2010/035z.html new file mode 100644 index 0000000..1a8b464 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/035z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>035z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "035" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + compiler bootstrapping + + write a basic version first, replace it with the actual version once the structure is in place + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/036.html b/static/talks/extending_moose_yapc_na_2010/036.html new file mode 100644 index 0000000..b989513 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/036.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>036</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "035z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/036z.html b/static/talks/extending_moose_yapc_na_2010/036z.html new file mode 100644 index 0000000..a784d1e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/036z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>036z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class + + so Class->meta->meta == Class->meta + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/037.html b/static/talks/extending_moose_yapc_na_2010/037.html new file mode 100644 index 0000000..177075e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/037.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>037</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "038" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + but this is mostly irrelevant + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/038.html b/static/talks/extending_moose_yapc_na_2010/038.html new file mode 100644 index 0000000..717a608 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/038.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>038</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "038z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + the idea to take away is that moose is built on top of moose + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/038z.html b/static/talks/extending_moose_yapc_na_2010/038z.html new file mode 100644 index 0000000..7e99519 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/038z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>038z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "038" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "039" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + the idea to take away is that moose is built on top of moose + + and so it can be extended just like any other moose object + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/039.html b/static/talks/extending_moose_yapc_na_2010/039.html new file mode 100644 index 0000000..3139ede --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/039.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>039</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "038z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "040" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + so we have this foundation, but how can we make this easy to use? + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/040.html b/static/talks/extending_moose_yapc_na_2010/040.html new file mode 100644 index 0000000..6f033bf --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/040.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>040</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "039" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "041" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + Moose::Exporter + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/041.html b/static/talks/extending_moose_yapc_na_2010/041.html new file mode 100644 index 0000000..d7626ff --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/041.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>041</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "040" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "041z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro')) + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/041z.html b/static/talks/extending_moose_yapc_na_2010/041z.html new file mode 100644 index 0000000..867de5e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/041z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>041z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "041" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro')) + + but we'd like "has foo => (is => 'ro')" + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/042.html b/static/talks/extending_moose_yapc_na_2010/042.html new file mode 100644 index 0000000..47d345e --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/042.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>042</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "041z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/042b.html b/static/talks/extending_moose_yapc_na_2010/042b.html new file mode 100644 index 0000000..9b05428 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/042b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>042b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality + + can curry the metaclass into helper functions + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/042z.html b/static/talks/extending_moose_yapc_na_2010/042z.html new file mode 100644 index 0000000..95e78d7 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/042z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>042z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality + + can curry the metaclass into helper functions + + can pass arguments to Moose::Util::MetaRole to customize the metaclasses + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/043.html b/static/talks/extending_moose_yapc_na_2010/043.html new file mode 100644 index 0000000..c9d052f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/043.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>043</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose itself uses Moose::Exporter + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/043b.html b/static/talks/extending_moose_yapc_na_2010/043b.html new file mode 100644 index 0000000..c6f0556 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/043b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>043b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose itself uses Moose::Exporter + + 'has' is a thin wrapper around __PACKAGE__->meta->add_attribute + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/043z.html b/static/talks/extending_moose_yapc_na_2010/043z.html new file mode 100644 index 0000000..cb34df7 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/043z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>043z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "044" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + Moose itself uses Moose::Exporter + + 'has' is a thin wrapper around __PACKAGE__->meta->add_attribute + + read the source to Moose.pm, it's pretty simple + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/044.html b/static/talks/extending_moose_yapc_na_2010/044.html new file mode 100644 index 0000000..f36b3ae --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/044.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>044</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "045" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + so the key here is that all of these metaclasses can be customized, and Moose::Exporter can wrap those customizations to make them pretty + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/045.html b/static/talks/extending_moose_yapc_na_2010/045.html new file mode 100644 index 0000000..cceaf7b --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/045.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>045</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "044" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "046.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + basic extensions don't even need to alter the metaclass + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/046.pl.html b/static/talks/extending_moose_yapc_na_2010/046.pl.html new file mode 100644 index 0000000..d7606ec --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/046.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>046.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "045" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "047.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> package FileAttributes; + use Moose::Exporter; + use MooseX::Types::Path::Class qw(File); + + Moose::Exporter->setup_import_methods( + with_meta => ['has_file'], + ); + + sub has_file { + my ($meta, $name, %options) = @_; + $meta->add_attribute( + $name, + is => 'ro', + isa => File, + coerce => 1, + %options, + ); + } +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/047.pl.html b/static/talks/extending_moose_yapc_na_2010/047.pl.html new file mode 100644 index 0000000..de2cf6b --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/047.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>047.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "046.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "048" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + package Foo; + use Moose; + use FileAttributes; + + has_file 'foo'; + has_file 'bar' => (required => 1); + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/048.html b/static/talks/extending_moose_yapc_na_2010/048.html new file mode 100644 index 0000000..06e902f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/048.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>048</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "047.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "049.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + but altering metaclasses can provide more powerful abstractions + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/049.pl.html b/static/talks/extending_moose_yapc_na_2010/049.pl.html new file mode 100644 index 0000000..cdd2d70 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/049.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>049.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "048" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "050.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + package AtomicMethod::Role::Method; + use Moose::Role; + + around wrap => sub { + my ($orig, $self, $body, @args) = @_; + my $new_body = sub { + warn "locking...\n"; # or something more useful + my @ret = $body->(@_); # TODO: handle context properly + warn "unlocking...\n"; # or something more useful + return @ret; + }; + $self->$orig($new_body, @args); + }; + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/050.pl.html b/static/talks/extending_moose_yapc_na_2010/050.pl.html new file mode 100644 index 0000000..b22e48f --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/050.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>050.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "049.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "050z.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> and make it pretty + + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/050z.pl.html b/static/talks/extending_moose_yapc_na_2010/050z.pl.html new file mode 100644 index 0000000..ca7312d --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/050z.pl.html @@ -0,0 +1,57 @@ +<html> +<head> +<title>050z.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "050.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "051.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> and make it pretty + + package AtomicMethod; + use Moose::Exporter; + + Moose::Exporter->setup_import_methods( + with_meta => [qw(atomic_method)], + ); + + sub _atomic_method_meta { + my ($meta) = @_; + Moose::Meta::Class->create_anon_class( + superclasses => [$meta->method_metaclass], + roles => ['AtomicMethod::Role::Method'], + cache => 1, + )->name; + } + + sub atomic_method { + my ($meta, $name, $code) = @_; + $meta->add_method( + $name => _atomic_method_meta($meta)->wrap( + $code, + name => $name, + package_name => $meta->name, + associated_metaclass => $meta + ), + ); + } +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/051.pl.html b/static/talks/extending_moose_yapc_na_2010/051.pl.html new file mode 100644 index 0000000..cc98caa --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/051.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>051.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "050z.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "052" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + package Foo; + use Moose; + use AtomicMethod; + + atomic_method foo => sub { + warn "in foo\n"; + }; + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/052.html b/static/talks/extending_moose_yapc_na_2010/052.html new file mode 100644 index 0000000..31c2f59 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/052.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>052</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "051.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "053.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + combining metaclass alterations can be even more powerful + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/053.pl.html b/static/talks/extending_moose_yapc_na_2010/053.pl.html new file mode 100644 index 0000000..7eecef6 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/053.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>053.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "052" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "054.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + package Command::Role::Method; + use Moose::Role; + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/054.pl.html b/static/talks/extending_moose_yapc_na_2010/054.pl.html new file mode 100644 index 0000000..b946994 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/054.pl.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>054.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "053.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "055.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> package Command::Role::Class; + use Moose::Role; + + sub get_all_commands { + my ($self) = @_; + grep { Moose::Util::does_role($_, 'Command::Role::Method') } + $self->get_all_methods; + } + + sub has_command { + my ($self, $name) = @_; + my $method = $self->find_method_by_name($name); + return unless $method; + return Moose::Util::does_role($method, 'Command::Role::Method'); + } + + sub get_command { + my ($self, $name) = @_; + my $method = $self->find_method_by_name($name); + return unless $method; + return Moose::Util::does_role($method, 'Command::Role::Method') + ? $method + : (); + } +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/055.pl.html b/static/talks/extending_moose_yapc_na_2010/055.pl.html new file mode 100644 index 0000000..84c098a --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/055.pl.html @@ -0,0 +1,58 @@ +<html> +<head> +<title>055.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "054.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "056.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> package Command; + use Moose::Exporter; + + Moose::Exporter->setup_import_methods( + with_meta => ['command'], + class_metaroles => { + class => ['Command::Role::Class'], + }, + ); + + sub _command_method_meta { + my ($meta) = @_; + Moose::Meta::Class->create_anon_class( + superclasses => [$meta->method_metaclass], + roles => ['Command::Role::Method'], + cache => 1, + )->name; + } + + sub command { + my ($meta, $name, $code) = @_; + $meta->add_method( + $name => _command_method_meta($meta)->wrap( + $code, + name => $name, + package_name => $meta->name, + associated_metaclass => $meta + ), + ); + } +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/056.pl.html b/static/talks/extending_moose_yapc_na_2010/056.pl.html new file mode 100644 index 0000000..1aed6f2 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/056.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>056.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "055.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "057.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + package Foo; + use Moose; + use Command; + + command bar => sub { ... }; + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/057.pl.html b/static/talks/extending_moose_yapc_na_2010/057.pl.html new file mode 100644 index 0000000..e7c7064 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/057.pl.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>057.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "056.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "058" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + package My::App; + use Moose; + use Foo; + + sub run { + my ($self, $cmd) = @_; + if (Foo->meta->has_command($cmd)) { + Foo->new->$cmd; + } + elsif ($cmd eq 'cmdlist') { + print join ', ', map { $_->name } Foo->meta->get_all_commands; + } + } + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/058.html b/static/talks/extending_moose_yapc_na_2010/058.html new file mode 100644 index 0000000..edde0f5 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/058.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>058</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "057.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "059.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + for larger projects, providing a custom exporter can simplify things greatly + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/059.pl.html b/static/talks/extending_moose_yapc_na_2010/059.pl.html new file mode 100644 index 0000000..673f2f2 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/059.pl.html @@ -0,0 +1,59 @@ +<html> +<head> +<title>059.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "058" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "060" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> package Mooose; + use Moose::Exporter; + use MooseX::NonMoose (); + use MooseX::Aliases (); + + my ($import, $unimport, $init_meta) = Moose::Exporter->build_import_methods( + also => ['MooseX::NonMoose', 'MooseX::Aliases'], + class_metaroles => { + class => ['My::App::Meta::Class'], + }, + ); + + sub import { + strict->import; + warnings->import; + autodie->import; + feature->import(':5.10'); + MooseX::Aliases->import; + goto $import; + } + + sub unimport { + # .... (s/import/unimport/ on the above) + goto $unimport; + } + + sub init_meta { + my ($package, %options) = @_; + die unless $options{for_class}->isa('My::Base::Class'); + goto $init_meta; + } +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/060.html b/static/talks/extending_moose_yapc_na_2010/060.html new file mode 100644 index 0000000..2202e92 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/060.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>060</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "059.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "061" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + the positive side + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/061.html b/static/talks/extending_moose_yapc_na_2010/061.html new file mode 100644 index 0000000..bf9f0b9 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/061.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>061</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "060" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "061b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + these things are easily packaged up into standalone modules + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/061b.html b/static/talks/extending_moose_yapc_na_2010/061b.html new file mode 100644 index 0000000..7fba6d3 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/061b.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>061b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "061" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "061c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + these things are easily packaged up into standalone modules + + * MooseX::FileAttributes + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/061c.html b/static/talks/extending_moose_yapc_na_2010/061c.html new file mode 100644 index 0000000..9681a82 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/061c.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>061c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "061b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "061d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + these things are easily packaged up into standalone modules + + * MooseX::FileAttributes + * MooseX::TransactionalMethods + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/061d.html b/static/talks/extending_moose_yapc_na_2010/061d.html new file mode 100644 index 0000000..603d4d1 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/061d.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>061d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "061c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "061z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + these things are easily packaged up into standalone modules + + * MooseX::FileAttributes + * MooseX::TransactionalMethods + * IM::Engine::Plugin::Commands + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/061z.html b/static/talks/extending_moose_yapc_na_2010/061z.html new file mode 100644 index 0000000..a344b82 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/061z.html @@ -0,0 +1,46 @@ +<html> +<head> +<title>061z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "061d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "062" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + these things are easily packaged up into standalone modules + + * MooseX::FileAttributes + * MooseX::TransactionalMethods + * IM::Engine::Plugin::Commands + * Blawd::OO, TAEB::OO, etc... + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/062.html b/static/talks/extending_moose_yapc_na_2010/062.html new file mode 100644 index 0000000..49d74df --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/062.html @@ -0,0 +1,42 @@ +<html> +<head> +<title>062</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "061z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + any questions? + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/index.html b/static/talks/extending_moose_yapc_na_2010/index.html new file mode 100644 index 0000000..c894505 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/index.html @@ -0,0 +1,97 @@ +<html> +<head> +<title>Extending Moose</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 13 || keynum == 32) { + window.location = "001.html"; + return false; + } + return true; +} +</script> +<style> +body { + font-family: sans-serif; +} +h4 { + color: #888; +} +</style> +</head> +<body> +<h4>Use SPACEBAR to peruse the slides or click one to start...<h4> +<h1>Extending Moose</h1> +<ul> +<li><a href="001.html">Extending Moose</a></li> +<li><a href="002.html">motivation</a></li> +<li><a href="003.html">moose</a></li> +<li><a href="004.html">using only the basic features doesn't gain you much</a></li> +<li><a href="005.pl.html">package Foo;</a></li> +<li><a href="006.pl.html">package Foo;</a></li> +<li><a href="007.pl.html">but...</a></li> +<li><a href="008.html">moose gives you more than this</a></li> +<li><a href="009.html">but the real power of moose is in extensibility</a></li> +<li><a href="010.html">typical object systems are defined in terms of, well, object systems</a></li> +<li><a href="011.html">code should be written with the intent of communicating with *humans*</a></li> +<li><a href="012.html">this has different levels:</a></li> +<li><a href="013.html">perl:</a></li> +<li><a href="014.html">moose (by default):</a></li> +<li><a href="015.html">but what we'd really like is:</a></li> +<li><a href="016.html">moose can give us this too</a></li> +<li><a href="017.html">the mop</a></li> +<li><a href="018.html">models classes as objects</a></li> +<li><a href="019.html">every class is represented by a metaclass</a></li> +<li><a href="020.html">Moose::Meta::Class</a></li> +<li><a href="021.html">access these objects through Class->meta (a class method installed by "use Moose")</a></li> +<li><a href="022.html">class information is stored and manipulated through these objects</a></li> +<li><a href="023.html">also provides informational methods</a></li> +<li><a href="024.html">and provides other functionality specific to the mop</a></li> +<li><a href="025.html">Moose::Meta::Attribute</a></li> +<li><a href="026.html">accessed through $meta->get_attribute, etc</a></li> +<li><a href="027.html">informational methods:</a></li> +<li><a href="028.html">accessing data handled by the attribute</a></li> +<li><a href="029.html">Moose::Meta::Method</a></li> +<li><a href="030.html">accessed through $meta->get_method, etc</a></li> +<li><a href="031.html">so how does this all work?</a></li> +<li><a href="032.html">metacircularity</a></li> +<li><a href="033.html">metaclasses are instances of the class Moose::Meta::Class</a></li> +<li><a href="034.html">this is accomplished by two tricks</a></li> +<li><a href="035.html">compiler bootstrapping</a></li> +<li><a href="036.html">Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class</a></li> +<li><a href="037.html">but this is mostly irrelevant</a></li> +<li><a href="038.html">the idea to take away is that moose is built on top of moose</a></li> +<li><a href="039.html">so we have this foundation, but how can we make this easy to use?</a></li> +<li><a href="040.html">Moose::Exporter</a></li> +<li><a href="041.html">we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro'))</a></li> +<li><a href="042.html">Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality</a></li> +<li><a href="043.html">Moose itself uses Moose::Exporter</a></li> +<li><a href="044.html">so the key here is that all of these metaclasses can be customized, and Moose::Exporter can wrap those customizations to make them pretty</a></li> +<li><a href="045.html">basic extensions don't even need to alter the metaclass</a></li> +<li><a href="046.pl.html">package FileAttributes;</a></li> +<li><a href="047.pl.html">package Foo;</a></li> +<li><a href="048.html">but altering metaclasses can provide more powerful abstractions</a></li> +<li><a href="049.pl.html">package AtomicMethod::Role::Method;</a></li> +<li><a href="050.pl.html">and make it pretty</a></li> +<li><a href="051.pl.html">package Foo;</a></li> +<li><a href="052.html">combining metaclass alterations can be even more powerful</a></li> +<li><a href="053.pl.html">package Command::Role::Method;</a></li> +<li><a href="054.pl.html">package Command::Role::Class;</a></li> +<li><a href="055.pl.html">package Command;</a></li> +<li><a href="056.pl.html">package Foo;</a></li> +<li><a href="057.pl.html">package My::App;</a></li> +<li><a href="058.html">for larger projects, providing a custom exporter can simplify things greatly</a></li> +<li><a href="059.pl.html">package Mooose;</a></li> +<li><a href="060.html">the positive side</a></li> +<li><a href="061.html">these things are easily packaged up into standalone modules</a></li> +<li><a href="062.html">any questions?</a></li> +</ul> +<p>This presentation was generated by <a +href="http://ingydotnet.github.com/vroom-pm">Vroom</a>. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +</p> +</body> diff --git a/static/talks/extending_moose_yapc_na_2010/slides.vroom b/static/talks/extending_moose_yapc_na_2010/slides.vroom new file mode 100644 index 0000000..7f27df3 --- /dev/null +++ b/static/talks/extending_moose_yapc_na_2010/slides.vroom @@ -0,0 +1,399 @@ +---- config +title: Extending Moose +indent: 8 +height: 18 +width: 69 +skip: 0 + +---- center +Extending Moose + +by Jesse Luehrs (doy at tozt dot net) + +---- +== motivation +---- +moose + ++great class builder + ++lots of beginner info available +---- +using only the basic features doesn't gain you much +---- perl,i4 +package Foo; +use base qw(Class::Accessor); +__PACKAGE__->mk_accessors('bar'); +---- perl,i4 +package Foo; +use Moose; +has bar => (is => 'ro'); +---- perl,i4 +but... + ++package Foo; +use Class::Accessor 'antlers'; +has bar => (is => 'ro'); +---- +moose gives you more than this + ++* builders ++* delegation ++* roles ++* etc... +---- +but the real power of moose is in extensibility +---- +typical object systems are defined in terms of, well, object systems + ++has input_file => ( + is => 'ro', + isa => File, + coerce => 1, + required => 1, +); + ++wouldn't it be nice to be able to say what we mean? + ++has_file 'input_file'; +---- +code should be written with the intent of communicating with *humans* + ++computers are great at figuring out the details on their own + ++write code in the language of the domain rather than the language of the computer +---- +this has different levels: +---- +perl: + +a user is a hash table with a key storing the username and a key storing the password, associated with a set of functions for manipulating those hash keys while validating them and ensuring they remain consistent +---- +moose (by default): + +a user has a readonly string attribute storing the username, and a read/write Authen::Passphrase object storing the password, which password checking is delegated to +---- +but what we'd really like is: + +a user has a name, and you can ask if its password is correct +---- +moose can give us this too +---- +== the mop + ++== (meta object protocol) +---- +models classes as objects +---- +every class is represented by a metaclass + ++a normal perl object of the class Moose::Meta::Class + ++contains attributes and methods as members (objects of Moose::Meta::Attribute and Moose::Meta::Method) + ++(other stuff too, but we'll ignore that for now) +---- +== Moose::Meta::Class +---- +access these objects through Class->meta (a class method installed by "use Moose") +---- +class information is stored and manipulated through these objects + ++* "@ISA = ('Foo')" -> "$meta->superclasses('Foo')" ++* "*foo = sub { ... }" -> "$meta->add_method(foo => sub { ... })" ++* "our $foo = 'bar'" -> "$meta->add_package_symbol('$foo' => 'bar')" +---- +also provides informational methods + ++* $meta->class_precedence_list ++* $meta->has_method('foo') ++* $meta->does_role('Role') +---- +and provides other functionality specific to the mop + ++* $meta->make_immutable ++* $meta->new_object ++* Moose::Meta::Class->create_anon_class +---- +== Moose::Meta::Attribute +---- +accessed through $meta->get_attribute, etc + ++stores data associated with an object + ++also handles installing methods associated with accessing that data +---- +informational methods: + ++* $meta_attr->get_read_method ++* $meta_attr->type_constraint +---- +accessing data handled by the attribute + ++$meta_attr->get_value($obj) +---- +== Moose::Meta::Method +---- +accessed through $meta->get_method, etc + ++represents a method associated with a class + ++these are typically introspected from the symbol table, not created explicitly + ++they can be created explicitly if necessary; this is how method modifiers work +---- +so how does this all work? +---- +== metacircularity +---- +metaclasses are instances of the class Moose::Meta::Class + ++but Moose::Meta::Class is itself a class + ++so it must have a metaclass +---- +this is accomplished by two tricks +---- +compiler bootstrapping + ++write a basic version first, replace it with the actual version once the structure is in place +---- +Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class + ++so Class->meta->meta == Class->meta +---- +but this is mostly irrelevant +---- +the idea to take away is that moose is built on top of moose + ++and so it can be extended just like any other moose object +---- +so we have this foundation, but how can we make this easy to use? +---- +== Moose::Exporter +---- +we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro')) + ++but we'd like "has foo => (is => 'ro')" +---- +Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality + ++can curry the metaclass into helper functions + ++can pass arguments to Moose::Util::MetaRole to customize the metaclasses +---- +Moose itself uses Moose::Exporter + ++'has' is a thin wrapper around __PACKAGE__->meta->add_attribute + ++read the source to Moose.pm, it's pretty simple +---- +so the key here is that all of these metaclasses can be customized, and Moose::Exporter can wrap those customizations to make them pretty +---- +basic extensions don't even need to alter the metaclass +---- perl,i4 +package FileAttributes; +use Moose::Exporter; +use MooseX::Types::Path::Class qw(File); + +Moose::Exporter->setup_import_methods( + with_meta => ['has_file'], +); + +sub has_file { + my ($meta, $name, %options) = @_; + $meta->add_attribute( + $name, + is => 'ro', + isa => File, + coerce => 1, + %options, + ); +} +---- perl,i4 +package Foo; +use Moose; +use FileAttributes; + +has_file 'foo'; +has_file 'bar' => (required => 1); +---- +but altering metaclasses can provide more powerful abstractions +---- perl,i4 +package AtomicMethod::Role::Method; +use Moose::Role; + +around wrap => sub { + my ($orig, $self, $body, @args) = @_; + my $new_body = sub { + warn "locking...\n"; # or something more useful + my @ret = $body->(@_); # TODO: handle context properly + warn "unlocking...\n"; # or something more useful + return @ret; + }; + $self->$orig($new_body, @args); +}; +---- perl,i4 +and make it pretty + ++package AtomicMethod; +use Moose::Exporter; + +Moose::Exporter->setup_import_methods( + with_meta => [qw(atomic_method)], +); + +sub _atomic_method_meta { + my ($meta) = @_; + Moose::Meta::Class->create_anon_class( + superclasses => [$meta->method_metaclass], + roles => ['AtomicMethod::Role::Method'], + cache => 1, + )->name; +} + +sub atomic_method { + my ($meta, $name, $code) = @_; + $meta->add_method( + $name => _atomic_method_meta($meta)->wrap( + $code, + name => $name, + package_name => $meta->name, + associated_metaclass => $meta + ), + ); +} +---- perl,i4 +package Foo; +use Moose; +use AtomicMethod; + +atomic_method foo => sub { + warn "in foo\n"; +}; +---- +combining metaclass alterations can be even more powerful +---- perl,i4 +package Command::Role::Method; +use Moose::Role; +---- perl,i4 +package Command::Role::Class; +use Moose::Role; + +sub get_all_commands { + my ($self) = @_; + grep { Moose::Util::does_role($_, 'Command::Role::Method') } + $self->get_all_methods; +} + +sub has_command { + my ($self, $name) = @_; + my $method = $self->find_method_by_name($name); + return unless $method; + return Moose::Util::does_role($method, 'Command::Role::Method'); +} + +sub get_command { + my ($self, $name) = @_; + my $method = $self->find_method_by_name($name); + return unless $method; + return Moose::Util::does_role($method, 'Command::Role::Method') + ? $method + : (); +} +---- perl,i4 +package Command; +use Moose::Exporter; + +Moose::Exporter->setup_import_methods( + with_meta => ['command'], + class_metaroles => { + class => ['Command::Role::Class'], + }, +); + +sub _command_method_meta { + my ($meta) = @_; + Moose::Meta::Class->create_anon_class( + superclasses => [$meta->method_metaclass], + roles => ['Command::Role::Method'], + cache => 1, + )->name; +} + +sub command { + my ($meta, $name, $code) = @_; + $meta->add_method( + $name => _command_method_meta($meta)->wrap( + $code, + name => $name, + package_name => $meta->name, + associated_metaclass => $meta + ), + ); +} +---- perl,i4 +package Foo; +use Moose; +use Command; + +command bar => sub { ... }; +---- perl,i4 +package My::App; +use Moose; +use Foo; + +sub run { + my ($self, $cmd) = @_; + if (Foo->meta->has_command($cmd)) { + Foo->new->$cmd; + } + elsif ($cmd eq 'cmdlist') { + print join ', ', map { $_->name } Foo->meta->get_all_commands; + } +} +---- +for larger projects, providing a custom exporter can simplify things greatly +---- perl,i4 +package Mooose; +use Moose::Exporter; +use MooseX::NonMoose (); +use MooseX::Aliases (); + +my ($import, $unimport, $init_meta) = Moose::Exporter->build_import_methods( + also => ['MooseX::NonMoose', 'MooseX::Aliases'], + class_metaroles => { + class => ['My::App::Meta::Class'], + }, +); + +sub import { + strict->import; + warnings->import; + autodie->import; + feature->import(':5.10'); + MooseX::Aliases->import; + goto $import; +} + +sub unimport { + # .... (s/import/unimport/ on the above) + goto $unimport; +} + +sub init_meta { + my ($package, %options) = @_; + die unless $options{for_class}->isa('My::Base::Class'); + goto $init_meta; +} +---- +the positive side +---- +these things are easily packaged up into standalone modules + ++* MooseX::FileAttributes ++* MooseX::TransactionalMethods ++* IM::Engine::Plugin::Commands ++* Blawd::OO, TAEB::OO, etc... +---- center +any questions? diff --git a/static/talks/ox_yapc_na_2011/001.html b/static/talks/ox_yapc_na_2011/001.html new file mode 100644 index 0000000..8198145 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/001.html @@ -0,0 +1,55 @@ +<html> +<head> +<title>001</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + OX + The hardest working two letters in Perl + + Jesse Luehrs, Infinity Interactive + + http://github.com/stevan/OX/ + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/002.html b/static/talks/ox_yapc_na_2011/002.html new file mode 100644 index 0000000..a44596b --- /dev/null +++ b/static/talks/ox_yapc_na_2011/002.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>002</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "001" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + history + + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/002b.html b/static/talks/ox_yapc_na_2011/002b.html new file mode 100644 index 0000000..9cbf8e7 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/002b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>002b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + history + + * custom app-specific stuff + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/002c.html b/static/talks/ox_yapc_na_2011/002c.html new file mode 100644 index 0000000..e08e3b4 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/002c.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>002c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + history + + * custom app-specific stuff + * CGI::Application + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/002d.html b/static/talks/ox_yapc_na_2011/002d.html new file mode 100644 index 0000000..a91e7c0 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/002d.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>002d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "002z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + history + + * custom app-specific stuff + * CGI::Application + * Catalyst + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/002z.html b/static/talks/ox_yapc_na_2011/002z.html new file mode 100644 index 0000000..8bd3718 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/002z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>002z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "003" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + history + + * custom app-specific stuff + * CGI::Application + * Catalyst + * Plack + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/003.html b/static/talks/ox_yapc_na_2011/003.html new file mode 100644 index 0000000..28fe492 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/003.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>003</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "002z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "004" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + OX - the web anti-framework + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/004.html b/static/talks/ox_yapc_na_2011/004.html new file mode 100644 index 0000000..d8f8072 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/004.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>004</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "003" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + Stevan + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/005.html b/static/talks/ox_yapc_na_2011/005.html new file mode 100644 index 0000000..0125c6a --- /dev/null +++ b/static/talks/ox_yapc_na_2011/005.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>005</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "004" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + what is OX? + + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/005b.html b/static/talks/ox_yapc_na_2011/005b.html new file mode 100644 index 0000000..1cda024 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/005b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>005b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + what is OX? + + * Bread::Board + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/005c.html b/static/talks/ox_yapc_na_2011/005c.html new file mode 100644 index 0000000..5fcee53 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/005c.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>005c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005d" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + what is OX? + + * Bread::Board + * Path::Router + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/005d.html b/static/talks/ox_yapc_na_2011/005d.html new file mode 100644 index 0000000..4f7227b --- /dev/null +++ b/static/talks/ox_yapc_na_2011/005d.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>005d</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "005z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + what is OX? + + * Bread::Board + * Path::Router + * Plack + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/005z.html b/static/talks/ox_yapc_na_2011/005z.html new file mode 100644 index 0000000..d95cb8c --- /dev/null +++ b/static/talks/ox_yapc_na_2011/005z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>005z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005d" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + what is OX? + + * Bread::Board + * Path::Router + * Plack + * EXPERIMENTAL + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/006.pl.html b/static/talks/ox_yapc_na_2011/006.pl.html new file mode 100644 index 0000000..ffc70df --- /dev/null +++ b/static/talks/ox_yapc_na_2011/006.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>006.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "005z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + # app.psgi + use OX; + + my $counter = 0; + + router as { + route '/' => sub { $counter }; + route '/inc' => sub { ++$counter }; + route '/dec' => sub { --$counter }; + route '/reset' => sub { $counter = 0 }; + route '/set/:num' => sub { $counter = $_[1] }, ( + num => { isa => 'Int' }, + ); + }; + + xo; + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/007.html b/static/talks/ox_yapc_na_2011/007.html new file mode 100644 index 0000000..06c5585 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/007.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>007</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "006.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "007z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + Bread::Board + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/007z.html b/static/talks/ox_yapc_na_2011/007z.html new file mode 100644 index 0000000..23f6e50 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/007z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>007z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + Bread::Board + control your object's construction + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/008.html b/static/talks/ox_yapc_na_2011/008.html new file mode 100644 index 0000000..32a4897 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/008.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>008</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "007z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Bread::Board has containers, containers contain services + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/008b.html b/static/talks/ox_yapc_na_2011/008b.html new file mode 100644 index 0000000..e65cc9f --- /dev/null +++ b/static/talks/ox_yapc_na_2011/008b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>008b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Bread::Board has containers, containers contain services + an OX application is a Bread::Board container + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/008z.html b/static/talks/ox_yapc_na_2011/008z.html new file mode 100644 index 0000000..8146d28 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/008z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>008z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Bread::Board has containers, containers contain services + an OX application is a Bread::Board container + all application objects are services in the container + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/009.html b/static/talks/ox_yapc_na_2011/009.html new file mode 100644 index 0000000..db93d88 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/009.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>009</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "008z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + services can depend on other services + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/009b.html b/static/talks/ox_yapc_na_2011/009b.html new file mode 100644 index 0000000..4b99ddc --- /dev/null +++ b/static/talks/ox_yapc_na_2011/009b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>009b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "009z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + services can depend on other services + dependencies are resolved first + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/009z.html b/static/talks/ox_yapc_na_2011/009z.html new file mode 100644 index 0000000..b0399ec --- /dev/null +++ b/static/talks/ox_yapc_na_2011/009z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>009z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "010" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + services can depend on other services + dependencies are resolved first + passed as constructor parameters to the requested service + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/010.html b/static/talks/ox_yapc_na_2011/010.html new file mode 100644 index 0000000..bc6cc44 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/010.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>010</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "009z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "011.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + at minimum, the router and the app coderef itself are services + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/011.pl.html b/static/talks/ox_yapc_na_2011/011.pl.html new file mode 100644 index 0000000..8ee8bbf --- /dev/null +++ b/static/talks/ox_yapc_na_2011/011.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>011.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "010" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "012.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + package App; + use OX; + + has model => (is => 'ro', isa => 'Model'); + has view => (is => 'ro', isa => 'View'); + has controller => ( + is => 'ro', + isa => 'Controller', + dependencies => ['model', 'view'], + ); + + router as { + route '/' => 'root.index'; + route '/inc' => 'root.inc'; + route '/dec' => 'root.dec'; + route '/reset' => 'root.reset'; + route '/set/:num' => 'root.set', ( + num => { isa => 'Int' }, + ); + }, (root => 'controller'); + + __PACKAGE__->meta->make_immutable; + 1; + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/012.pl.html b/static/talks/ox_yapc_na_2011/012.pl.html new file mode 100644 index 0000000..96cd998 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/012.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>012.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "011.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "013" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + package Controller; + use Moose; + + has view => (is => 'ro', isa => 'View', required => 1); + has model => (is => 'ro', isa => 'Model', required => 1); + + sub index { } + sub inc { my $self = shift; $self->model->inc } + sub dec { my $self = shift; $self->model->dec } + sub reset { my $self = shift; $self->model->reset } + sub set { my $self = shift; $self->model->set($_[1]) } + + around [qw(index inc dec set reset)] => sub { + my $orig = shift; + my $self = shift; + $self->$orig(@_); + return $self->view->render($self->model->count); + }; + + __PACKAGE__->meta->make_immutable; + 1; + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/013.html b/static/talks/ox_yapc_na_2011/013.html new file mode 100644 index 0000000..5f408cd --- /dev/null +++ b/static/talks/ox_yapc_na_2011/013.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>013</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "012.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "013b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Path::Router + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/013b.html b/static/talks/ox_yapc_na_2011/013b.html new file mode 100644 index 0000000..3f95de1 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/013b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>013b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "013" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "013z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Path::Router + translate incoming urls into structured data + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/013z.html b/static/talks/ox_yapc_na_2011/013z.html new file mode 100644 index 0000000..34098f6 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/013z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>013z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "013b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "014.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Path::Router + translate incoming urls into structured data + also translate structured data into urls + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/014.pl.html b/static/talks/ox_yapc_na_2011/014.pl.html new file mode 100644 index 0000000..6a12f3f --- /dev/null +++ b/static/talks/ox_yapc_na_2011/014.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>014.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "013z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + route '/set/:num' => 'root.set', ( + num => { isa => 'Int' }, + ); + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/015.html b/static/talks/ox_yapc_na_2011/015.html new file mode 100644 index 0000000..face2c8 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/015.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>015</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "014.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "015z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + /set/23 -> { num => 23 } + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/015z.html b/static/talks/ox_yapc_na_2011/015z.html new file mode 100644 index 0000000..a1e9d1a --- /dev/null +++ b/static/talks/ox_yapc_na_2011/015z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>015z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + /set/23 -> { num => 23 } + not just the hashref, but also the code to call for this path + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/016.html b/static/talks/ox_yapc_na_2011/016.html new file mode 100644 index 0000000..31324a0 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/016.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>016</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "015z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "017.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + bidirectional + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/017.pl.html b/static/talks/ox_yapc_na_2011/017.pl.html new file mode 100644 index 0000000..33b08a3 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/017.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>017.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "016" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "018" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + $router->uri_for({num => 23}); # '/set/23' + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/018.html b/static/talks/ox_yapc_na_2011/018.html new file mode 100644 index 0000000..c5cf4d8 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/018.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>018</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "017.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "018b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + this translation is controlled by OX, and is pluggable + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/018b.html b/static/talks/ox_yapc_na_2011/018b.html new file mode 100644 index 0000000..a4b87a2 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/018b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>018b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "018" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "018z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + this translation is controlled by OX, and is pluggable + already seen examples + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/018z.html b/static/talks/ox_yapc_na_2011/018z.html new file mode 100644 index 0000000..b95a595 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/018z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>018z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "018b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "019.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + this translation is controlled by OX, and is pluggable + already seen examples + route '/' => sub { ... } + route '/' => 'root.index' + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/019.pl.html b/static/talks/ox_yapc_na_2011/019.pl.html new file mode 100644 index 0000000..c9f6863 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/019.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>019.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "018z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + has root => (is => 'ro', isa => 'Controller'); + + router ['HTTPMethod'] => as { + route '/' => 'root'; + }, (root => 'root'); + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/020.html b/static/talks/ox_yapc_na_2011/020.html new file mode 100644 index 0000000..ac93b16 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/020.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>020</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "019.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "020z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + GET request for '/' will call Controller::get + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/020z.html b/static/talks/ox_yapc_na_2011/020z.html new file mode 100644 index 0000000..7956fa7 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/020z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>020z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "020" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "021" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + GET request for '/' will call Controller::get + POST request for '/' will call Controller::post + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/021.html b/static/talks/ox_yapc_na_2011/021.html new file mode 100644 index 0000000..244af7c --- /dev/null +++ b/static/talks/ox_yapc_na_2011/021.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>021</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "020z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "022.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + this is just the sugar layer + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/022.pl.html b/static/talks/ox_yapc_na_2011/022.pl.html new file mode 100644 index 0000000..fc6ae76 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/022.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>022.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "021" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "023" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + package App; + use OX; + + sub configure_router { ... } + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/023.html b/static/talks/ox_yapc_na_2011/023.html new file mode 100644 index 0000000..2692e5a --- /dev/null +++ b/static/talks/ox_yapc_na_2011/023.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>023</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "022.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "024.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + or, you can replace the router entirely + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/024.pl.html b/static/talks/ox_yapc_na_2011/024.pl.html new file mode 100644 index 0000000..c2ebc7d --- /dev/null +++ b/static/talks/ox_yapc_na_2011/024.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>024.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "023" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "025" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + router 'My::Custom::Router::Class'; + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/025.html b/static/talks/ox_yapc_na_2011/025.html new file mode 100644 index 0000000..8c0336d --- /dev/null +++ b/static/talks/ox_yapc_na_2011/025.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>025</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "024.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + Plack + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/026.html b/static/talks/ox_yapc_na_2011/026.html new file mode 100644 index 0000000..5d47883 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/026.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>026</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "025" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + OX applications provide the Plack::Component api + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/026z.html b/static/talks/ox_yapc_na_2011/026z.html new file mode 100644 index 0000000..f24de1c --- /dev/null +++ b/static/talks/ox_yapc_na_2011/026z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>026z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + OX applications provide the Plack::Component api + ->prepare_app + ->call + ->to_app + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/027.html b/static/talks/ox_yapc_na_2011/027.html new file mode 100644 index 0000000..162825b --- /dev/null +++ b/static/talks/ox_yapc_na_2011/027.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>027</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "026z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + two types of middleware + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/027b.html b/static/talks/ox_yapc_na_2011/027b.html new file mode 100644 index 0000000..d8e2b59 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/027b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>027b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "027z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + two types of middleware + deployment (Stacktrace, ReverseProxy) + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/027z.html b/static/talks/ox_yapc_na_2011/027z.html new file mode 100644 index 0000000..8e97a48 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/027z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>027z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + two types of middleware + deployment (Stacktrace, ReverseProxy) + app-specific (Session) + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/028.html b/static/talks/ox_yapc_na_2011/028.html new file mode 100644 index 0000000..5368ab5 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/028.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>028</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "027z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "029.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + your application class should be able to declare app-specific middleware + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/029.pl.html b/static/talks/ox_yapc_na_2011/029.pl.html new file mode 100644 index 0000000..44456c7 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/029.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>029.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "028" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "030.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + router as { + wrap 'Plack::Middleware::Session'; + route '/' => ...; + }; + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/030.pl.html b/static/talks/ox_yapc_na_2011/030.pl.html new file mode 100644 index 0000000..eb4f260 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/030.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>030.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "029.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + has session_store => ( + is => 'ro', + isa => 'Str', + value => 'File', + ); + + router as { + wrap 'Plack::Middleware::Session' => ( + store => 'session_store', + ); + route '/' => ...; + }; + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/031.html b/static/talks/ox_yapc_na_2011/031.html new file mode 100644 index 0000000..3ac17bc --- /dev/null +++ b/static/talks/ox_yapc_na_2011/031.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>031</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "030.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "032.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + again, this is just the sugar layer + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/032.pl.html b/static/talks/ox_yapc_na_2011/032.pl.html new file mode 100644 index 0000000..f300495 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/032.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>032.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "031" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "033.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + package App; + use Moose; + extends 'OX::Application'; + + sub configure_router { + ... + } + + sub app_from_router { + ... + } + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/033.pl.html b/static/talks/ox_yapc_na_2011/033.pl.html new file mode 100644 index 0000000..927e723 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/033.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>033.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "032.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + package App; + use Moose; + use Bread::Board; + extends 'OX::Application'; + + sub BUILD { + my $self = shift; + container $self => as { + ... + }; + } + + sub configure_router { + ... + } + + sub app_from_router { + ... + } + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/034.html b/static/talks/ox_yapc_na_2011/034.html new file mode 100644 index 0000000..bbebf8f --- /dev/null +++ b/static/talks/ox_yapc_na_2011/034.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>034</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "033.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "035" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + benefits of OX + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/035.html b/static/talks/ox_yapc_na_2011/035.html new file mode 100644 index 0000000..233541a --- /dev/null +++ b/static/talks/ox_yapc_na_2011/035.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>035</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "034" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "035z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + reuse + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/035z.html b/static/talks/ox_yapc_na_2011/035z.html new file mode 100644 index 0000000..3d8e626 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/035z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>035z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "035" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "036.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + reuse + no wrapper classes required + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/036.pl.html b/static/talks/ox_yapc_na_2011/036.pl.html new file mode 100644 index 0000000..f9deefe --- /dev/null +++ b/static/talks/ox_yapc_na_2011/036.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>036.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "035z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "037.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + package App; + use OX; + + has model => (is => 'ro', isa => 'KiokuX::Model'); + has view => (is => 'ro', isa => 'Template'); + + ... + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/037.pl.html b/static/talks/ox_yapc_na_2011/037.pl.html new file mode 100644 index 0000000..d7aab4e --- /dev/null +++ b/static/talks/ox_yapc_na_2011/037.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>037.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "036.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "038" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + package App; + use OX; + + has dsn => (is => 'ro', isa => 'Str', default => 'dbi:sqlite:app.sqlite'); + has root => (is => 'ro', isa => 'Str', default => 'root/templates'); + + has model => ( + is => 'ro', + isa => 'KiokuX::Model', + dependencies => ['dsn'], + ); + has view => ( + is => 'ro', + isa => 'Template', + dependencies => { INCLUDE_PATH => 'root' }, + ); + + ... + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/038.html b/static/talks/ox_yapc_na_2011/038.html new file mode 100644 index 0000000..3ff5b17 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/038.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>038</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "037.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "039.pl" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + application classes are decoupled, and can be used independently + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/039.pl.html b/static/talks/ox_yapc_na_2011/039.pl.html new file mode 100644 index 0000000..8e6d00e --- /dev/null +++ b/static/talks/ox_yapc_na_2011/039.pl.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>039.pl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "038" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "040" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + App->new->model + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/040.html b/static/talks/ox_yapc_na_2011/040.html new file mode 100644 index 0000000..8f4847e --- /dev/null +++ b/static/talks/ox_yapc_na_2011/040.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>040</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "039.pl" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "040b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + get the model object exactly as it would be initialized within the app + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/040b.html b/static/talks/ox_yapc_na_2011/040b.html new file mode 100644 index 0000000..35596db --- /dev/null +++ b/static/talks/ox_yapc_na_2011/040b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>040b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "040" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "040z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + get the model object exactly as it would be initialized within the app + except without initializing the app + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/040z.html b/static/talks/ox_yapc_na_2011/040z.html new file mode 100644 index 0000000..f962fb6 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/040z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>040z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "040b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "041" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + get the model object exactly as it would be initialized within the app + except without initializing the app + very useful for standalone scripts + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/041.html b/static/talks/ox_yapc_na_2011/041.html new file mode 100644 index 0000000..e69e4a1 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/041.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>041</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "040z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + App->new(dsn => 'dbi:SQLite::memory:')->to_app + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/042.html b/static/talks/ox_yapc_na_2011/042.html new file mode 100644 index 0000000..6902569 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/042.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>042</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "041" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + override specific bits of the application at initialization time + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/042b.html b/static/talks/ox_yapc_na_2011/042b.html new file mode 100644 index 0000000..23f6979 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/042b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>042b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "042z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + override specific bits of the application at initialization time + makes testing very easy + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/042z.html b/static/talks/ox_yapc_na_2011/042z.html new file mode 100644 index 0000000..9fd7517 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/042z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>042z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + override specific bits of the application at initialization time + makes testing very easy + simple way to fit in mock objects, or adjust configuration for tests + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/043.html b/static/talks/ox_yapc_na_2011/043.html new file mode 100644 index 0000000..775474b --- /dev/null +++ b/static/talks/ox_yapc_na_2011/043.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>043</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "042z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + the entire structure is just building on existing technology + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/043b.html b/static/talks/ox_yapc_na_2011/043b.html new file mode 100644 index 0000000..287e7fa --- /dev/null +++ b/static/talks/ox_yapc_na_2011/043b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>043b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043c" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + the entire structure is just building on existing technology + applications can use roles and inheritance + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/043c.html b/static/talks/ox_yapc_na_2011/043c.html new file mode 100644 index 0000000..eabf5e3 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/043c.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>043c</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "043z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + the entire structure is just building on existing technology + applications can use roles and inheritance + middleware just works + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/043z.html b/static/talks/ox_yapc_na_2011/043z.html new file mode 100644 index 0000000..6e92ab1 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/043z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>043z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043c" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "044" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + the entire structure is just building on existing technology + applications can use roles and inheritance + middleware just works + components are just normal classes, can be built however you want + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/044.html b/static/talks/ox_yapc_na_2011/044.html new file mode 100644 index 0000000..7815a60 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/044.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>044</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "043z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "045" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + TODO + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/045.html b/static/talks/ox_yapc_na_2011/045.html new file mode 100644 index 0000000..6ec60ab --- /dev/null +++ b/static/talks/ox_yapc_na_2011/045.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>045</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "044" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "045z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + nested applications need work + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/045z.html b/static/talks/ox_yapc_na_2011/045z.html new file mode 100644 index 0000000..6fd7376 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/045z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>045z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "045" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "046" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + nested applications need work + in particular, how can services be shared? + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/046.html b/static/talks/ox_yapc_na_2011/046.html new file mode 100644 index 0000000..15ed09d --- /dev/null +++ b/static/talks/ox_yapc_na_2011/046.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>046</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "045z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "046z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + bread::board subcontainers + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/046z.html b/static/talks/ox_yapc_na_2011/046z.html new file mode 100644 index 0000000..652c406 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/046z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>046z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "046" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "047" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + bread::board subcontainers + need a syntax for this + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/047.html b/static/talks/ox_yapc_na_2011/047.html new file mode 100644 index 0000000..4c34c12 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/047.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>047</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "046z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "047z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + more extensible routebuilders + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/047z.html b/static/talks/ox_yapc_na_2011/047z.html new file mode 100644 index 0000000..552e354 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/047z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>047z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "047" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "048" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + + more extensible routebuilders + want a way to let the controller object control the dispatching + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/048.html b/static/talks/ox_yapc_na_2011/048.html new file mode 100644 index 0000000..6ea3361 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/048.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>048</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "047z" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "048b" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + cleaner underlying foundation + + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/048b.html b/static/talks/ox_yapc_na_2011/048b.html new file mode 100644 index 0000000..91346df --- /dev/null +++ b/static/talks/ox_yapc_na_2011/048b.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>048b</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "048" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "048z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + cleaner underlying foundation + more ways to customize the router + + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/048z.html b/static/talks/ox_yapc_na_2011/048z.html new file mode 100644 index 0000000..d33c48b --- /dev/null +++ b/static/talks/ox_yapc_na_2011/048z.html @@ -0,0 +1,56 @@ +<html> +<head> +<title>048z</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "048b" + ".html"; + return false; + } + if (keynum == 13 || keynum == 32) { + window.location = "049" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + cleaner underlying foundation + more ways to customize the router + more ways to customize the container + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/049.html b/static/talks/ox_yapc_na_2011/049.html new file mode 100644 index 0000000..110f4cf --- /dev/null +++ b/static/talks/ox_yapc_na_2011/049.html @@ -0,0 +1,52 @@ +<html> +<head> +<title>049</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 8) { + window.location = "048z" + ".html"; + return false; + } + if (keynum == 73 || keynum == 105) { + window.location = "index.html"; + return false; + } + return true; +} +</script> +</head> +<body onkeypress="return navigate(event)"> +<pre> + + + + + + + + + + + Any questions? + + http://github.com/stevan/OX/ + + + + + + + + + + + + + + +</pre> +</body> diff --git a/static/talks/ox_yapc_na_2011/index.html b/static/talks/ox_yapc_na_2011/index.html new file mode 100644 index 0000000..3687174 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/index.html @@ -0,0 +1,84 @@ +<html> +<head> +<title>OX - The hardest working two letters in Perl</title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<script> +function navigate(e) { + var keynum = (window.event) // IE + ? e.keyCode + : e.which; + if (keynum == 13 || keynum == 32) { + window.location = "001.html"; + return false; + } + return true; +} +</script> +<style> +body { + font-family: sans-serif; +} +h4 { + color: #888; +} +</style> +</head> +<body> +<h4>Use SPACEBAR to peruse the slides or click one to start...<h4> +<h1>OX - The hardest working two letters in Perl</h1> +<ul> +<li><a href="001.html">OX</a></li> +<li><a href="002.html">history</a></li> +<li><a href="003.html">OX - the web anti-framework</a></li> +<li><a href="004.html">Stevan</a></li> +<li><a href="005.html">what is OX?</a></li> +<li><a href="006.pl.html"># app.psgi</a></li> +<li><a href="007.html">Bread::Board</a></li> +<li><a href="008.html">Bread::Board has containers, containers contain services</a></li> +<li><a href="009.html">services can depend on other services</a></li> +<li><a href="010.html">at minimum, the router and the app coderef itself are services</a></li> +<li><a href="011.pl.html">package App;</a></li> +<li><a href="012.pl.html">package Controller;</a></li> +<li><a href="013.html">Path::Router</a></li> +<li><a href="014.pl.html">route '/set/:num' => 'root.set', (</a></li> +<li><a href="015.html">/set/23 -> { num => 23 }</a></li> +<li><a href="016.html">bidirectional</a></li> +<li><a href="017.pl.html">$router->uri_for({num => 23}); # '/set/23'</a></li> +<li><a href="018.html">this translation is controlled by OX, and is pluggable</a></li> +<li><a href="019.pl.html">has root => (is => 'ro', isa => 'Controller');</a></li> +<li><a href="020.html">GET request for '/' will call Controller::get</a></li> +<li><a href="021.html">this is just the sugar layer</a></li> +<li><a href="022.pl.html">package App;</a></li> +<li><a href="023.html">or, you can replace the router entirely</a></li> +<li><a href="024.pl.html">router 'My::Custom::Router::Class';</a></li> +<li><a href="025.html">Plack</a></li> +<li><a href="026.html">OX applications provide the Plack::Component api</a></li> +<li><a href="027.html">two types of middleware</a></li> +<li><a href="028.html">your application class should be able to declare app-specific middleware</a></li> +<li><a href="029.pl.html">router as {</a></li> +<li><a href="030.pl.html">has session_store => (</a></li> +<li><a href="031.html">again, this is just the sugar layer</a></li> +<li><a href="032.pl.html">package App;</a></li> +<li><a href="033.pl.html">package App;</a></li> +<li><a href="034.html">benefits of OX</a></li> +<li><a href="035.html">reuse</a></li> +<li><a href="036.pl.html">package App;</a></li> +<li><a href="037.pl.html">package App;</a></li> +<li><a href="038.html">application classes are decoupled, and can be used independently</a></li> +<li><a href="039.pl.html">App->new->model</a></li> +<li><a href="040.html">get the model object exactly as it would be initialized within the app</a></li> +<li><a href="041.html">App->new(dsn => 'dbi:SQLite::memory:')->to_app</a></li> +<li><a href="042.html">override specific bits of the application at initialization time</a></li> +<li><a href="043.html">the entire structure is just building on existing technology</a></li> +<li><a href="044.html">TODO</a></li> +<li><a href="045.html">nested applications need work</a></li> +<li><a href="046.html">bread::board subcontainers</a></li> +<li><a href="047.html">more extensible routebuilders</a></li> +<li><a href="048.html">cleaner underlying foundation</a></li> +<li><a href="049.html">Any questions?</a></li> +</ul> +<p>This presentation was generated by <a +href="http://ingydotnet.github.com/vroom-pm">Vroom</a>. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +</p> +</body> diff --git a/static/talks/ox_yapc_na_2011/slides.vroom b/static/talks/ox_yapc_na_2011/slides.vroom new file mode 100644 index 0000000..c013537 --- /dev/null +++ b/static/talks/ox_yapc_na_2011/slides.vroom @@ -0,0 +1,366 @@ +---- config +title: OX - The hardest working two letters in Perl +indent: 4 +height: 28 +width: 80 +skip: 0 +vimrc: colorscheme zellner + +---- center + +OX +The hardest working two letters in Perl + +Jesse Luehrs, Infinity Interactive + +http://github.com/stevan/OX/ + +---- + +== history + ++* custom app-specific stuff ++* CGI::Application ++* Catalyst ++* Plack + +---- center + +OX - the web anti-framework + +---- center + +== Stevan + +---- + +== what is OX? + ++* Bread::Board ++* Path::Router ++* Plack ++* EXPERIMENTAL + +---- perl,i4 + +---- include app.psgi + +---- + +Bread::Board ++control your object's construction + +---- + +Bread::Board has containers, containers contain services ++an OX application is a Bread::Board container ++all application objects are services in the container + +---- + +services can depend on other services ++dependencies are resolved first ++passed as constructor parameters to the requested service + +---- + +at minimum, the router and the app coderef itself are services + +---- perl,i4 + +package App; +use OX; + +has model => (is => 'ro', isa => 'Model'); +has view => (is => 'ro', isa => 'View'); +has controller => ( + is => 'ro', + isa => 'Controller', + dependencies => ['model', 'view'], +); + +router as { + route '/' => 'root.index'; + route '/inc' => 'root.inc'; + route '/dec' => 'root.dec'; + route '/reset' => 'root.reset'; + route '/set/:num' => 'root.set', ( + num => { isa => 'Int' }, + ); +}, (root => 'controller'); + +__PACKAGE__->meta->make_immutable; +1; + +---- perl,i4 + +package Controller; +use Moose; + +has view => (is => 'ro', isa => 'View', required => 1); +has model => (is => 'ro', isa => 'Model', required => 1); + +sub index { } +sub inc { my $self = shift; $self->model->inc } +sub dec { my $self = shift; $self->model->dec } +sub reset { my $self = shift; $self->model->reset } +sub set { my $self = shift; $self->model->set($_[1]) } + +around [qw(index inc dec set reset)] => sub { + my $orig = shift; + my $self = shift; + $self->$orig(@_); + return $self->view->render($self->model->count); +}; + +__PACKAGE__->meta->make_immutable; +1; + +---- + +Path::Router ++translate incoming urls into structured data ++also translate structured data into urls + +---- perl,i4 + +route '/set/:num' => 'root.set', ( + num => { isa => 'Int' }, +); + +---- + +/set/23 -> { num => 23 } ++not just the hashref, but also the code to call for this path + +---- + +bidirectional + +---- perl,i4 + +$router->uri_for({num => 23}); # '/set/23' + +---- + +this translation is controlled by OX, and is pluggable ++already seen examples ++route '/' => sub { ... } +route '/' => 'root.index' + +---- perl,i4 + +has root => (is => 'ro', isa => 'Controller'); + +router ['HTTPMethod'] => as { + route '/' => 'root'; +}, (root => 'root'); + +---- + +GET request for '/' will call Controller::get ++POST request for '/' will call Controller::post + +---- + +this is just the sugar layer + +---- perl,i4 + +package App; +use OX; + +sub configure_router { ... } + +---- + +or, you can replace the router entirely + +---- perl,i4 + +router 'My::Custom::Router::Class'; + +---- + +Plack + +---- + +OX applications provide the Plack::Component api ++->prepare_app +->call +->to_app + +---- + +two types of middleware ++deployment (Stacktrace, ReverseProxy) ++app-specific (Session) + +---- + +your application class should be able to declare app-specific middleware + +---- perl,i4 + +router as { + wrap 'Plack::Middleware::Session'; + route '/' => ...; +}; + +---- perl,i4 + +has session_store => ( + is => 'ro', + isa => 'Str', + value => 'File', +); + +router as { + wrap 'Plack::Middleware::Session' => ( + store => 'session_store', + ); + route '/' => ...; +}; + +---- + +again, this is just the sugar layer + +---- perl,i4 + +package App; +use Moose; +extends 'OX::Application'; + +sub configure_router { + ... +} + +sub app_from_router { + ... +} + +---- perl,i4 + +package App; +use Moose; +use Bread::Board; +extends 'OX::Application'; + +sub BUILD { + my $self = shift; + container $self => as { + ... + }; +} + +sub configure_router { + ... +} + +sub app_from_router { + ... +} + +---- + +benefits of OX + +---- + +reuse ++no wrapper classes required + +---- perl,i4 + +package App; +use OX; + +has model => (is => 'ro', isa => 'KiokuX::Model'); +has view => (is => 'ro', isa => 'Template'); + +... + +---- perl,i4 + +package App; +use OX; + +has dsn => (is => 'ro', isa => 'Str', default => 'dbi:sqlite:app.sqlite'); +has root => (is => 'ro', isa => 'Str', default => 'root/templates'); + +has model => ( + is => 'ro', + isa => 'KiokuX::Model', + dependencies => ['dsn'], +); +has view => ( + is => 'ro', + isa => 'Template', + dependencies => { INCLUDE_PATH => 'root' }, +); + +... + +---- + +application classes are decoupled, and can be used independently + +---- perl,i4 + +App->new->model + +---- + +get the model object exactly as it would be initialized within the app ++except without initializing the app ++very useful for standalone scripts + +---- + +App->new(dsn => 'dbi:SQLite::memory:')->to_app + +---- + +override specific bits of the application at initialization time ++makes testing very easy ++simple way to fit in mock objects, or adjust configuration for tests + +---- + +the entire structure is just building on existing technology ++applications can use roles and inheritance ++middleware just works ++components are just normal classes, can be built however you want + +---- + +TODO + +---- + +nested applications need work ++in particular, how can services be shared? + +---- + +bread::board subcontainers ++need a syntax for this + +---- + +more extensible routebuilders ++want a way to let the controller object control the dispatching + +---- + +cleaner underlying foundation ++more ways to customize the router ++more ways to customize the container + +---- center + +Any questions? + +http://github.com/stevan/OX/ |