From aa403b978860210fcbace7fcdf5830066f3e14e0 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 13 Oct 2018 02:17:44 -0400 Subject: import site content --- static/blog/cartridge.jpg | Bin 0 -> 274982 bytes static/blog/input.s | 135 ++++++ static/blog/sprites.chr | Bin 0 -> 8192 bytes static/blog/sprites.s | 197 ++++++++ static/talks/bread_board_yapc_eu_2012.key | Bin 0 -> 4229667 bytes static/talks/bread_board_yapc_eu_2012.pdf | Bin 0 -> 1058806 bytes static/talks/bread_board_yapc_na_2012/001.html | 51 +++ static/talks/bread_board_yapc_na_2012/002.html | 52 +++ static/talks/bread_board_yapc_na_2012/003.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/004.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/005.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/006.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/007.html | 52 +++ static/talks/bread_board_yapc_na_2012/007b.html | 52 +++ static/talks/bread_board_yapc_na_2012/007c.html | 52 +++ static/talks/bread_board_yapc_na_2012/007z.html | 52 +++ static/talks/bread_board_yapc_na_2012/008.html | 52 +++ static/talks/bread_board_yapc_na_2012/008b.html | 52 +++ static/talks/bread_board_yapc_na_2012/008c.html | 52 +++ static/talks/bread_board_yapc_na_2012/008z.html | 52 +++ static/talks/bread_board_yapc_na_2012/009.html | 53 +++ static/talks/bread_board_yapc_na_2012/009z.html | 52 +++ static/talks/bread_board_yapc_na_2012/010.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/011.html | 52 +++ static/talks/bread_board_yapc_na_2012/011b.html | 52 +++ static/talks/bread_board_yapc_na_2012/011c.html | 52 +++ static/talks/bread_board_yapc_na_2012/011z.html | 52 +++ static/talks/bread_board_yapc_na_2012/012.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/013.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/014.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/015.html | 52 +++ static/talks/bread_board_yapc_na_2012/015b.html | 52 +++ static/talks/bread_board_yapc_na_2012/015c.html | 52 +++ static/talks/bread_board_yapc_na_2012/015z.html | 52 +++ static/talks/bread_board_yapc_na_2012/016.html | 52 +++ static/talks/bread_board_yapc_na_2012/016b.html | 52 +++ static/talks/bread_board_yapc_na_2012/016z.html | 52 +++ static/talks/bread_board_yapc_na_2012/017.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/018.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/019.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/020.html | 52 +++ static/talks/bread_board_yapc_na_2012/020z.html | 52 +++ static/talks/bread_board_yapc_na_2012/021.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/022.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/023.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/024.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/025.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/026.html | 52 +++ static/talks/bread_board_yapc_na_2012/026b.html | 52 +++ static/talks/bread_board_yapc_na_2012/026c.html | 52 +++ static/talks/bread_board_yapc_na_2012/026z.html | 52 +++ static/talks/bread_board_yapc_na_2012/027.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/028.html | 52 +++ static/talks/bread_board_yapc_na_2012/028b.html | 52 +++ static/talks/bread_board_yapc_na_2012/028c.html | 52 +++ static/talks/bread_board_yapc_na_2012/028d.html | 52 +++ static/talks/bread_board_yapc_na_2012/028z.html | 52 +++ static/talks/bread_board_yapc_na_2012/029.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/030.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/031.html | 52 +++ static/talks/bread_board_yapc_na_2012/031b.html | 52 +++ static/talks/bread_board_yapc_na_2012/031c.html | 52 +++ static/talks/bread_board_yapc_na_2012/031z.html | 52 +++ static/talks/bread_board_yapc_na_2012/032.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/033.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/034.html | 52 +++ static/talks/bread_board_yapc_na_2012/034b.html | 52 +++ static/talks/bread_board_yapc_na_2012/034z.html | 52 +++ static/talks/bread_board_yapc_na_2012/035.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/036.html | 52 +++ static/talks/bread_board_yapc_na_2012/036b.html | 52 +++ static/talks/bread_board_yapc_na_2012/036c.html | 52 +++ static/talks/bread_board_yapc_na_2012/036d.html | 52 +++ static/talks/bread_board_yapc_na_2012/036z.html | 52 +++ static/talks/bread_board_yapc_na_2012/037.html | 52 +++ static/talks/bread_board_yapc_na_2012/037b.html | 52 +++ static/talks/bread_board_yapc_na_2012/037c.html | 52 +++ static/talks/bread_board_yapc_na_2012/037z.html | 52 +++ static/talks/bread_board_yapc_na_2012/038.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/039.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/040.pl.html | 52 +++ static/talks/bread_board_yapc_na_2012/041.html | 48 ++ static/talks/bread_board_yapc_na_2012/index.html | 76 +++ static/talks/bread_board_yapc_na_2012/slides.vroom | 508 +++++++++++++++++++++ static/talks/extending_moose_yapc_na_2010/001.html | 45 ++ static/talks/extending_moose_yapc_na_2010/002.html | 46 ++ static/talks/extending_moose_yapc_na_2010/003.html | 46 ++ .../talks/extending_moose_yapc_na_2010/003b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/003z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/004.html | 46 ++ .../talks/extending_moose_yapc_na_2010/005.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/006.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/007.pl.html | 46 ++ .../extending_moose_yapc_na_2010/007z.pl.html | 46 ++ static/talks/extending_moose_yapc_na_2010/008.html | 46 ++ .../talks/extending_moose_yapc_na_2010/008b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/008c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/008d.html | 46 ++ .../talks/extending_moose_yapc_na_2010/008z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/009.html | 46 ++ static/talks/extending_moose_yapc_na_2010/010.html | 46 ++ .../talks/extending_moose_yapc_na_2010/010b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/010c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/010z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/011.html | 46 ++ .../talks/extending_moose_yapc_na_2010/011b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/011z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/012.html | 46 ++ static/talks/extending_moose_yapc_na_2010/013.html | 46 ++ static/talks/extending_moose_yapc_na_2010/014.html | 46 ++ static/talks/extending_moose_yapc_na_2010/015.html | 46 ++ static/talks/extending_moose_yapc_na_2010/016.html | 46 ++ static/talks/extending_moose_yapc_na_2010/017.html | 46 ++ .../talks/extending_moose_yapc_na_2010/017z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/018.html | 46 ++ static/talks/extending_moose_yapc_na_2010/019.html | 46 ++ .../talks/extending_moose_yapc_na_2010/019b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/019c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/019z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/020.html | 46 ++ static/talks/extending_moose_yapc_na_2010/021.html | 46 ++ static/talks/extending_moose_yapc_na_2010/022.html | 46 ++ .../talks/extending_moose_yapc_na_2010/022b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/022c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/022z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/023.html | 46 ++ .../talks/extending_moose_yapc_na_2010/023b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/023c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/023z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/024.html | 46 ++ .../talks/extending_moose_yapc_na_2010/024b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/024c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/024z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/025.html | 46 ++ static/talks/extending_moose_yapc_na_2010/026.html | 46 ++ .../talks/extending_moose_yapc_na_2010/026b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/026z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/027.html | 46 ++ .../talks/extending_moose_yapc_na_2010/027b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/027z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/028.html | 46 ++ .../talks/extending_moose_yapc_na_2010/028z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/029.html | 46 ++ static/talks/extending_moose_yapc_na_2010/030.html | 46 ++ .../talks/extending_moose_yapc_na_2010/030b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/030c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/030z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/031.html | 46 ++ static/talks/extending_moose_yapc_na_2010/032.html | 46 ++ static/talks/extending_moose_yapc_na_2010/033.html | 46 ++ .../talks/extending_moose_yapc_na_2010/033b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/033z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/034.html | 46 ++ static/talks/extending_moose_yapc_na_2010/035.html | 46 ++ .../talks/extending_moose_yapc_na_2010/035z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/036.html | 46 ++ .../talks/extending_moose_yapc_na_2010/036z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/037.html | 46 ++ static/talks/extending_moose_yapc_na_2010/038.html | 46 ++ .../talks/extending_moose_yapc_na_2010/038z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/039.html | 46 ++ static/talks/extending_moose_yapc_na_2010/040.html | 46 ++ static/talks/extending_moose_yapc_na_2010/041.html | 46 ++ .../talks/extending_moose_yapc_na_2010/041z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/042.html | 46 ++ .../talks/extending_moose_yapc_na_2010/042b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/042z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/043.html | 46 ++ .../talks/extending_moose_yapc_na_2010/043b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/043z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/044.html | 46 ++ static/talks/extending_moose_yapc_na_2010/045.html | 46 ++ .../talks/extending_moose_yapc_na_2010/046.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/047.pl.html | 46 ++ static/talks/extending_moose_yapc_na_2010/048.html | 46 ++ .../talks/extending_moose_yapc_na_2010/049.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/050.pl.html | 46 ++ .../extending_moose_yapc_na_2010/050z.pl.html | 57 +++ .../talks/extending_moose_yapc_na_2010/051.pl.html | 46 ++ static/talks/extending_moose_yapc_na_2010/052.html | 46 ++ .../talks/extending_moose_yapc_na_2010/053.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/054.pl.html | 52 +++ .../talks/extending_moose_yapc_na_2010/055.pl.html | 58 +++ .../talks/extending_moose_yapc_na_2010/056.pl.html | 46 ++ .../talks/extending_moose_yapc_na_2010/057.pl.html | 46 ++ static/talks/extending_moose_yapc_na_2010/058.html | 46 ++ .../talks/extending_moose_yapc_na_2010/059.pl.html | 59 +++ static/talks/extending_moose_yapc_na_2010/060.html | 46 ++ static/talks/extending_moose_yapc_na_2010/061.html | 46 ++ .../talks/extending_moose_yapc_na_2010/061b.html | 46 ++ .../talks/extending_moose_yapc_na_2010/061c.html | 46 ++ .../talks/extending_moose_yapc_na_2010/061d.html | 46 ++ .../talks/extending_moose_yapc_na_2010/061z.html | 46 ++ static/talks/extending_moose_yapc_na_2010/062.html | 42 ++ .../talks/extending_moose_yapc_na_2010/index.html | 97 ++++ .../extending_moose_yapc_na_2010/slides.vroom | 399 ++++++++++++++++ static/talks/ox_yapc_na_2011/001.html | 55 +++ static/talks/ox_yapc_na_2011/002.html | 56 +++ static/talks/ox_yapc_na_2011/002b.html | 56 +++ static/talks/ox_yapc_na_2011/002c.html | 56 +++ static/talks/ox_yapc_na_2011/002d.html | 56 +++ static/talks/ox_yapc_na_2011/002z.html | 56 +++ static/talks/ox_yapc_na_2011/003.html | 56 +++ static/talks/ox_yapc_na_2011/004.html | 56 +++ static/talks/ox_yapc_na_2011/005.html | 56 +++ static/talks/ox_yapc_na_2011/005b.html | 56 +++ static/talks/ox_yapc_na_2011/005c.html | 56 +++ static/talks/ox_yapc_na_2011/005d.html | 56 +++ static/talks/ox_yapc_na_2011/005z.html | 56 +++ static/talks/ox_yapc_na_2011/006.pl.html | 56 +++ static/talks/ox_yapc_na_2011/007.html | 56 +++ static/talks/ox_yapc_na_2011/007z.html | 56 +++ static/talks/ox_yapc_na_2011/008.html | 56 +++ static/talks/ox_yapc_na_2011/008b.html | 56 +++ static/talks/ox_yapc_na_2011/008z.html | 56 +++ static/talks/ox_yapc_na_2011/009.html | 56 +++ static/talks/ox_yapc_na_2011/009b.html | 56 +++ static/talks/ox_yapc_na_2011/009z.html | 56 +++ static/talks/ox_yapc_na_2011/010.html | 56 +++ static/talks/ox_yapc_na_2011/011.pl.html | 56 +++ static/talks/ox_yapc_na_2011/012.pl.html | 56 +++ static/talks/ox_yapc_na_2011/013.html | 56 +++ static/talks/ox_yapc_na_2011/013b.html | 56 +++ static/talks/ox_yapc_na_2011/013z.html | 56 +++ static/talks/ox_yapc_na_2011/014.pl.html | 56 +++ static/talks/ox_yapc_na_2011/015.html | 56 +++ static/talks/ox_yapc_na_2011/015z.html | 56 +++ static/talks/ox_yapc_na_2011/016.html | 56 +++ static/talks/ox_yapc_na_2011/017.pl.html | 56 +++ static/talks/ox_yapc_na_2011/018.html | 56 +++ static/talks/ox_yapc_na_2011/018b.html | 56 +++ static/talks/ox_yapc_na_2011/018z.html | 56 +++ static/talks/ox_yapc_na_2011/019.pl.html | 56 +++ static/talks/ox_yapc_na_2011/020.html | 56 +++ static/talks/ox_yapc_na_2011/020z.html | 56 +++ static/talks/ox_yapc_na_2011/021.html | 56 +++ static/talks/ox_yapc_na_2011/022.pl.html | 56 +++ static/talks/ox_yapc_na_2011/023.html | 56 +++ static/talks/ox_yapc_na_2011/024.pl.html | 56 +++ static/talks/ox_yapc_na_2011/025.html | 56 +++ static/talks/ox_yapc_na_2011/026.html | 56 +++ static/talks/ox_yapc_na_2011/026z.html | 56 +++ static/talks/ox_yapc_na_2011/027.html | 56 +++ static/talks/ox_yapc_na_2011/027b.html | 56 +++ static/talks/ox_yapc_na_2011/027z.html | 56 +++ static/talks/ox_yapc_na_2011/028.html | 56 +++ static/talks/ox_yapc_na_2011/029.pl.html | 56 +++ static/talks/ox_yapc_na_2011/030.pl.html | 56 +++ static/talks/ox_yapc_na_2011/031.html | 56 +++ static/talks/ox_yapc_na_2011/032.pl.html | 56 +++ static/talks/ox_yapc_na_2011/033.pl.html | 56 +++ static/talks/ox_yapc_na_2011/034.html | 56 +++ static/talks/ox_yapc_na_2011/035.html | 56 +++ static/talks/ox_yapc_na_2011/035z.html | 56 +++ static/talks/ox_yapc_na_2011/036.pl.html | 56 +++ static/talks/ox_yapc_na_2011/037.pl.html | 56 +++ static/talks/ox_yapc_na_2011/038.html | 56 +++ static/talks/ox_yapc_na_2011/039.pl.html | 56 +++ static/talks/ox_yapc_na_2011/040.html | 56 +++ static/talks/ox_yapc_na_2011/040b.html | 56 +++ static/talks/ox_yapc_na_2011/040z.html | 56 +++ static/talks/ox_yapc_na_2011/041.html | 56 +++ static/talks/ox_yapc_na_2011/042.html | 56 +++ static/talks/ox_yapc_na_2011/042b.html | 56 +++ static/talks/ox_yapc_na_2011/042z.html | 56 +++ static/talks/ox_yapc_na_2011/043.html | 56 +++ static/talks/ox_yapc_na_2011/043b.html | 56 +++ static/talks/ox_yapc_na_2011/043c.html | 56 +++ static/talks/ox_yapc_na_2011/043z.html | 56 +++ static/talks/ox_yapc_na_2011/044.html | 56 +++ static/talks/ox_yapc_na_2011/045.html | 56 +++ static/talks/ox_yapc_na_2011/045z.html | 56 +++ static/talks/ox_yapc_na_2011/046.html | 56 +++ static/talks/ox_yapc_na_2011/046z.html | 56 +++ static/talks/ox_yapc_na_2011/047.html | 56 +++ static/talks/ox_yapc_na_2011/047z.html | 56 +++ static/talks/ox_yapc_na_2011/048.html | 56 +++ static/talks/ox_yapc_na_2011/048b.html | 56 +++ static/talks/ox_yapc_na_2011/048z.html | 56 +++ static/talks/ox_yapc_na_2011/049.html | 52 +++ static/talks/ox_yapc_na_2011/index.html | 84 ++++ static/talks/ox_yapc_na_2011/slides.vroom | 366 +++++++++++++++ 282 files changed, 15606 insertions(+) create mode 100644 static/blog/cartridge.jpg create mode 100644 static/blog/input.s create mode 100644 static/blog/sprites.chr create mode 100644 static/blog/sprites.s create mode 100644 static/talks/bread_board_yapc_eu_2012.key create mode 100644 static/talks/bread_board_yapc_eu_2012.pdf create mode 100644 static/talks/bread_board_yapc_na_2012/001.html create mode 100644 static/talks/bread_board_yapc_na_2012/002.html create mode 100644 static/talks/bread_board_yapc_na_2012/003.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/004.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/005.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/006.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/007.html create mode 100644 static/talks/bread_board_yapc_na_2012/007b.html create mode 100644 static/talks/bread_board_yapc_na_2012/007c.html create mode 100644 static/talks/bread_board_yapc_na_2012/007z.html create mode 100644 static/talks/bread_board_yapc_na_2012/008.html create mode 100644 static/talks/bread_board_yapc_na_2012/008b.html create mode 100644 static/talks/bread_board_yapc_na_2012/008c.html create mode 100644 static/talks/bread_board_yapc_na_2012/008z.html create mode 100644 static/talks/bread_board_yapc_na_2012/009.html create mode 100644 static/talks/bread_board_yapc_na_2012/009z.html create mode 100644 static/talks/bread_board_yapc_na_2012/010.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/011.html create mode 100644 static/talks/bread_board_yapc_na_2012/011b.html create mode 100644 static/talks/bread_board_yapc_na_2012/011c.html create mode 100644 static/talks/bread_board_yapc_na_2012/011z.html create mode 100644 static/talks/bread_board_yapc_na_2012/012.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/013.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/014.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/015.html create mode 100644 static/talks/bread_board_yapc_na_2012/015b.html create mode 100644 static/talks/bread_board_yapc_na_2012/015c.html create mode 100644 static/talks/bread_board_yapc_na_2012/015z.html create mode 100644 static/talks/bread_board_yapc_na_2012/016.html create mode 100644 static/talks/bread_board_yapc_na_2012/016b.html create mode 100644 static/talks/bread_board_yapc_na_2012/016z.html create mode 100644 static/talks/bread_board_yapc_na_2012/017.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/018.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/019.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/020.html create mode 100644 static/talks/bread_board_yapc_na_2012/020z.html create mode 100644 static/talks/bread_board_yapc_na_2012/021.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/022.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/023.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/024.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/025.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/026.html create mode 100644 static/talks/bread_board_yapc_na_2012/026b.html create mode 100644 static/talks/bread_board_yapc_na_2012/026c.html create mode 100644 static/talks/bread_board_yapc_na_2012/026z.html create mode 100644 static/talks/bread_board_yapc_na_2012/027.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/028.html create mode 100644 static/talks/bread_board_yapc_na_2012/028b.html create mode 100644 static/talks/bread_board_yapc_na_2012/028c.html create mode 100644 static/talks/bread_board_yapc_na_2012/028d.html create mode 100644 static/talks/bread_board_yapc_na_2012/028z.html create mode 100644 static/talks/bread_board_yapc_na_2012/029.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/030.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/031.html create mode 100644 static/talks/bread_board_yapc_na_2012/031b.html create mode 100644 static/talks/bread_board_yapc_na_2012/031c.html create mode 100644 static/talks/bread_board_yapc_na_2012/031z.html create mode 100644 static/talks/bread_board_yapc_na_2012/032.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/033.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/034.html create mode 100644 static/talks/bread_board_yapc_na_2012/034b.html create mode 100644 static/talks/bread_board_yapc_na_2012/034z.html create mode 100644 static/talks/bread_board_yapc_na_2012/035.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/036.html create mode 100644 static/talks/bread_board_yapc_na_2012/036b.html create mode 100644 static/talks/bread_board_yapc_na_2012/036c.html create mode 100644 static/talks/bread_board_yapc_na_2012/036d.html create mode 100644 static/talks/bread_board_yapc_na_2012/036z.html create mode 100644 static/talks/bread_board_yapc_na_2012/037.html create mode 100644 static/talks/bread_board_yapc_na_2012/037b.html create mode 100644 static/talks/bread_board_yapc_na_2012/037c.html create mode 100644 static/talks/bread_board_yapc_na_2012/037z.html create mode 100644 static/talks/bread_board_yapc_na_2012/038.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/039.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/040.pl.html create mode 100644 static/talks/bread_board_yapc_na_2012/041.html create mode 100644 static/talks/bread_board_yapc_na_2012/index.html create mode 100644 static/talks/bread_board_yapc_na_2012/slides.vroom create mode 100644 static/talks/extending_moose_yapc_na_2010/001.html create mode 100644 static/talks/extending_moose_yapc_na_2010/002.html create mode 100644 static/talks/extending_moose_yapc_na_2010/003.html create mode 100644 static/talks/extending_moose_yapc_na_2010/003b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/003z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/004.html create mode 100644 static/talks/extending_moose_yapc_na_2010/005.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/006.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/007.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/007z.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/008.html create mode 100644 static/talks/extending_moose_yapc_na_2010/008b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/008c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/008d.html create mode 100644 static/talks/extending_moose_yapc_na_2010/008z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/009.html create mode 100644 static/talks/extending_moose_yapc_na_2010/010.html create mode 100644 static/talks/extending_moose_yapc_na_2010/010b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/010c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/010z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/011.html create mode 100644 static/talks/extending_moose_yapc_na_2010/011b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/011z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/012.html create mode 100644 static/talks/extending_moose_yapc_na_2010/013.html create mode 100644 static/talks/extending_moose_yapc_na_2010/014.html create mode 100644 static/talks/extending_moose_yapc_na_2010/015.html create mode 100644 static/talks/extending_moose_yapc_na_2010/016.html create mode 100644 static/talks/extending_moose_yapc_na_2010/017.html create mode 100644 static/talks/extending_moose_yapc_na_2010/017z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/018.html create mode 100644 static/talks/extending_moose_yapc_na_2010/019.html create mode 100644 static/talks/extending_moose_yapc_na_2010/019b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/019c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/019z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/020.html create mode 100644 static/talks/extending_moose_yapc_na_2010/021.html create mode 100644 static/talks/extending_moose_yapc_na_2010/022.html create mode 100644 static/talks/extending_moose_yapc_na_2010/022b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/022c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/022z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/023.html create mode 100644 static/talks/extending_moose_yapc_na_2010/023b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/023c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/023z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/024.html create mode 100644 static/talks/extending_moose_yapc_na_2010/024b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/024c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/024z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/025.html create mode 100644 static/talks/extending_moose_yapc_na_2010/026.html create mode 100644 static/talks/extending_moose_yapc_na_2010/026b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/026z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/027.html create mode 100644 static/talks/extending_moose_yapc_na_2010/027b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/027z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/028.html create mode 100644 static/talks/extending_moose_yapc_na_2010/028z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/029.html create mode 100644 static/talks/extending_moose_yapc_na_2010/030.html create mode 100644 static/talks/extending_moose_yapc_na_2010/030b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/030c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/030z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/031.html create mode 100644 static/talks/extending_moose_yapc_na_2010/032.html create mode 100644 static/talks/extending_moose_yapc_na_2010/033.html create mode 100644 static/talks/extending_moose_yapc_na_2010/033b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/033z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/034.html create mode 100644 static/talks/extending_moose_yapc_na_2010/035.html create mode 100644 static/talks/extending_moose_yapc_na_2010/035z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/036.html create mode 100644 static/talks/extending_moose_yapc_na_2010/036z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/037.html create mode 100644 static/talks/extending_moose_yapc_na_2010/038.html create mode 100644 static/talks/extending_moose_yapc_na_2010/038z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/039.html create mode 100644 static/talks/extending_moose_yapc_na_2010/040.html create mode 100644 static/talks/extending_moose_yapc_na_2010/041.html create mode 100644 static/talks/extending_moose_yapc_na_2010/041z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/042.html create mode 100644 static/talks/extending_moose_yapc_na_2010/042b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/042z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/043.html create mode 100644 static/talks/extending_moose_yapc_na_2010/043b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/043z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/044.html create mode 100644 static/talks/extending_moose_yapc_na_2010/045.html create mode 100644 static/talks/extending_moose_yapc_na_2010/046.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/047.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/048.html create mode 100644 static/talks/extending_moose_yapc_na_2010/049.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/050.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/050z.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/051.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/052.html create mode 100644 static/talks/extending_moose_yapc_na_2010/053.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/054.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/055.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/056.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/057.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/058.html create mode 100644 static/talks/extending_moose_yapc_na_2010/059.pl.html create mode 100644 static/talks/extending_moose_yapc_na_2010/060.html create mode 100644 static/talks/extending_moose_yapc_na_2010/061.html create mode 100644 static/talks/extending_moose_yapc_na_2010/061b.html create mode 100644 static/talks/extending_moose_yapc_na_2010/061c.html create mode 100644 static/talks/extending_moose_yapc_na_2010/061d.html create mode 100644 static/talks/extending_moose_yapc_na_2010/061z.html create mode 100644 static/talks/extending_moose_yapc_na_2010/062.html create mode 100644 static/talks/extending_moose_yapc_na_2010/index.html create mode 100644 static/talks/extending_moose_yapc_na_2010/slides.vroom create mode 100644 static/talks/ox_yapc_na_2011/001.html create mode 100644 static/talks/ox_yapc_na_2011/002.html create mode 100644 static/talks/ox_yapc_na_2011/002b.html create mode 100644 static/talks/ox_yapc_na_2011/002c.html create mode 100644 static/talks/ox_yapc_na_2011/002d.html create mode 100644 static/talks/ox_yapc_na_2011/002z.html create mode 100644 static/talks/ox_yapc_na_2011/003.html create mode 100644 static/talks/ox_yapc_na_2011/004.html create mode 100644 static/talks/ox_yapc_na_2011/005.html create mode 100644 static/talks/ox_yapc_na_2011/005b.html create mode 100644 static/talks/ox_yapc_na_2011/005c.html create mode 100644 static/talks/ox_yapc_na_2011/005d.html create mode 100644 static/talks/ox_yapc_na_2011/005z.html create mode 100644 static/talks/ox_yapc_na_2011/006.pl.html create mode 100644 static/talks/ox_yapc_na_2011/007.html create mode 100644 static/talks/ox_yapc_na_2011/007z.html create mode 100644 static/talks/ox_yapc_na_2011/008.html create mode 100644 static/talks/ox_yapc_na_2011/008b.html create mode 100644 static/talks/ox_yapc_na_2011/008z.html create mode 100644 static/talks/ox_yapc_na_2011/009.html create mode 100644 static/talks/ox_yapc_na_2011/009b.html create mode 100644 static/talks/ox_yapc_na_2011/009z.html create mode 100644 static/talks/ox_yapc_na_2011/010.html create mode 100644 static/talks/ox_yapc_na_2011/011.pl.html create mode 100644 static/talks/ox_yapc_na_2011/012.pl.html create mode 100644 static/talks/ox_yapc_na_2011/013.html create mode 100644 static/talks/ox_yapc_na_2011/013b.html create mode 100644 static/talks/ox_yapc_na_2011/013z.html create mode 100644 static/talks/ox_yapc_na_2011/014.pl.html create mode 100644 static/talks/ox_yapc_na_2011/015.html create mode 100644 static/talks/ox_yapc_na_2011/015z.html create mode 100644 static/talks/ox_yapc_na_2011/016.html create mode 100644 static/talks/ox_yapc_na_2011/017.pl.html create mode 100644 static/talks/ox_yapc_na_2011/018.html create mode 100644 static/talks/ox_yapc_na_2011/018b.html create mode 100644 static/talks/ox_yapc_na_2011/018z.html create mode 100644 static/talks/ox_yapc_na_2011/019.pl.html create mode 100644 static/talks/ox_yapc_na_2011/020.html create mode 100644 static/talks/ox_yapc_na_2011/020z.html create mode 100644 static/talks/ox_yapc_na_2011/021.html create mode 100644 static/talks/ox_yapc_na_2011/022.pl.html create mode 100644 static/talks/ox_yapc_na_2011/023.html create mode 100644 static/talks/ox_yapc_na_2011/024.pl.html create mode 100644 static/talks/ox_yapc_na_2011/025.html create mode 100644 static/talks/ox_yapc_na_2011/026.html create mode 100644 static/talks/ox_yapc_na_2011/026z.html create mode 100644 static/talks/ox_yapc_na_2011/027.html create mode 100644 static/talks/ox_yapc_na_2011/027b.html create mode 100644 static/talks/ox_yapc_na_2011/027z.html create mode 100644 static/talks/ox_yapc_na_2011/028.html create mode 100644 static/talks/ox_yapc_na_2011/029.pl.html create mode 100644 static/talks/ox_yapc_na_2011/030.pl.html create mode 100644 static/talks/ox_yapc_na_2011/031.html create mode 100644 static/talks/ox_yapc_na_2011/032.pl.html create mode 100644 static/talks/ox_yapc_na_2011/033.pl.html create mode 100644 static/talks/ox_yapc_na_2011/034.html create mode 100644 static/talks/ox_yapc_na_2011/035.html create mode 100644 static/talks/ox_yapc_na_2011/035z.html create mode 100644 static/talks/ox_yapc_na_2011/036.pl.html create mode 100644 static/talks/ox_yapc_na_2011/037.pl.html create mode 100644 static/talks/ox_yapc_na_2011/038.html create mode 100644 static/talks/ox_yapc_na_2011/039.pl.html create mode 100644 static/talks/ox_yapc_na_2011/040.html create mode 100644 static/talks/ox_yapc_na_2011/040b.html create mode 100644 static/talks/ox_yapc_na_2011/040z.html create mode 100644 static/talks/ox_yapc_na_2011/041.html create mode 100644 static/talks/ox_yapc_na_2011/042.html create mode 100644 static/talks/ox_yapc_na_2011/042b.html create mode 100644 static/talks/ox_yapc_na_2011/042z.html create mode 100644 static/talks/ox_yapc_na_2011/043.html create mode 100644 static/talks/ox_yapc_na_2011/043b.html create mode 100644 static/talks/ox_yapc_na_2011/043c.html create mode 100644 static/talks/ox_yapc_na_2011/043z.html create mode 100644 static/talks/ox_yapc_na_2011/044.html create mode 100644 static/talks/ox_yapc_na_2011/045.html create mode 100644 static/talks/ox_yapc_na_2011/045z.html create mode 100644 static/talks/ox_yapc_na_2011/046.html create mode 100644 static/talks/ox_yapc_na_2011/046z.html create mode 100644 static/talks/ox_yapc_na_2011/047.html create mode 100644 static/talks/ox_yapc_na_2011/047z.html create mode 100644 static/talks/ox_yapc_na_2011/048.html create mode 100644 static/talks/ox_yapc_na_2011/048b.html create mode 100644 static/talks/ox_yapc_na_2011/048z.html create mode 100644 static/talks/ox_yapc_na_2011/049.html create mode 100644 static/talks/ox_yapc_na_2011/index.html create mode 100644 static/talks/ox_yapc_na_2011/slides.vroom (limited to 'static') diff --git a/static/blog/cartridge.jpg b/static/blog/cartridge.jpg new file mode 100644 index 0000000..e6d70ae Binary files /dev/null and b/static/blog/cartridge.jpg differ 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 new file mode 100644 index 0000000..3713c9c Binary files /dev/null and b/static/blog/sprites.chr differ 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 new file mode 100644 index 0000000..d8e3a5f Binary files /dev/null and b/static/talks/bread_board_yapc_eu_2012.key differ diff --git a/static/talks/bread_board_yapc_eu_2012.pdf b/static/talks/bread_board_yapc_eu_2012.pdf new file mode 100644 index 0000000..22c82f8 Binary files /dev/null and b/static/talks/bread_board_yapc_eu_2012.pdf differ 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 @@ + + +001 + + + + +
+
+
+
+
+
+
+
+                     Dependency Injection with Bread::Board
+
+                                  Jesse Luehrs
+                              Infinity Interactive
+                                  doy@cpan.org
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002 + + + + +
+
+
+
+
+
+
+
+
+
+                              A Motivating Example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +003.pl + + + + +
+
+
+
+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;
+}
+
+
+
+
+
+
+
+ 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 @@ + + +004.pl + + + + +
+
+
+
+
+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);
+}
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005.pl + + + + +
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);
+}
+
+
+
+
+ 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 @@ + + +006.pl + + + + +
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 { ... }
+
+
+
+ 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 @@ + + +007 + + + + +
+
+
+
+
+
+
+
+    Dependency Injection
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007b + + + + +
+
+
+
+
+
+
+
+    Dependency Injection
+    
+     · a form of inversion of control
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007c + + + + +
+
+
+
+
+
+
+
+    Dependency Injection
+    
+     · a form of inversion of control
+     · "the inverse of garbage collection"
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007z + + + + +
+
+
+
+
+
+
+
+    Dependency Injection
+    
+     · a form of inversion of control
+     · "the inverse of garbage collection"
+     · manages object construction
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008 + + + + +
+
+
+
+
+
+
+
+    Benefits to Dependency Injection
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008b + + + + +
+
+
+
+
+
+
+
+    Benefits to Dependency Injection
+    
+     · provides access to the same object creation code
+       that your app will actually use
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008c + + + + +
+
+
+
+
+
+
+
+    Benefits to Dependency Injection
+    
+     · provides access to the same object creation code
+       that your app will actually use
+     · removes need for globals
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008z + + + + +
+
+
+
+
+
+
+
+    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
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +009 + + + + +
                                  Bread::Board
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +009z + + + + +
                                  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 |
+                  +-----------------------------------------+
+
+
+
+ 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 @@ + + +010.pl + + + + +
                                  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');
+
+
+
+ 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 @@ + + +011 + + + + +
+
+
+
+
+
+
+
+                                    Services
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011b + + + + +
+
+
+
+
+
+
+
+                                    Services
+    
+     · represent the data you're storing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011c + + + + +
+
+
+
+
+
+
+
+                                    Services
+    
+     · represent the data you're storing
+     · access contents via the ->get method
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011z + + + + +
+
+
+
+
+
+
+
+                                    Services
+    
+     · represent the data you're storing
+     · access contents via the ->get method
+     · three built-in types:
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +012.pl + + + + +
+
+
+
+
+
+
+
+                       Bread::Board::ConstructorInjection
+    
+    service view => (
+        class => 'View',
+    );
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +013.pl + + + + +
+
+
+
+
+
+                          Bread::Board::BlockInjection
+    
+    service model => (
+        class => 'Model', # optional
+        block => sub {
+            my $m = Model->new
+            $m->initialize;
+            return $m;
+        },
+    );
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +014.pl + + + + +
+
+
+
+
+
+
+
+
+                             Bread::Board::Literal
+    
+    service dsn => 'dbi:mysql:myapp_db';
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015 + + + + +
+
+
+
+
+
+
+
+                                   Containers
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015b + + + + +
+
+
+
+
+
+
+
+                                   Containers
+    
+     · hold services and other containers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015c + + + + +
+
+
+
+
+
+
+
+                                   Containers
+    
+     · hold services and other containers
+     · access contents via the ->fetch method
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015z + + + + +
+
+
+
+
+
+
+
+                                   Containers
+    
+     · hold services and other containers
+     · access contents via the ->fetch method
+       · ->resolve is a shortcut method for ->fetch(...)->get
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +016 + + + + +
+
+
+
+
+
+
+
+                                  Dependencies
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +016b + + + + +
+
+
+
+
+
+
+
+                                  Dependencies
+    
+     · tells Bread::Board how your classes are related
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +016z + + + + +
+
+
+
+
+
+
+
+                                  Dependencies
+    
+     · tells Bread::Board how your classes are related
+     · specified as a map of names to service paths
+       (there are shortcuts for common cases)
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +017.pl + + + + +
+
+
+
+
+
+
+                                  Dependencies
+
+service logger => (class => 'Logger');
+service view => (
+    class        => 'View',
+    dependencies => ['logger'],
+);
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +018.pl + + + + +
+
+
+
+
+                                  Dependencies
+
+service dsn => 'dbi:mysql:myapp_db';
+service model => (
+    class        => 'Model',
+    dependencies => ['dsn'],
+    block        => sub {
+        my $service = shift;
+        return Model->connect($service->param('dsn'));
+    },
+);
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019.pl + + + + +
+                                  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'],
+    );
+};
+
+
+
+
+
+ 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 @@ + + +020 + + + + +
+
+
+
+
+
+
+
+
+                                   Parameters
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +020z + + + + +
+
+
+
+
+
+
+
+
+                                   Parameters
+    
+     · like dependencies, but supplied when calling ->get or ->resolve
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +021.pl + + + + +
+
+
+
+
+                                   Parameters
+
+my $c = container MyApp => as {
+    service user => (
+        class => 'User',
+        parameters => {
+            name => { isa => 'Str' },
+        },
+    );
+};
+$c->resolve(service => 'user', parameters => { name => 'doy' });
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022.pl + + + + +
+
+
+                                   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' } },
+        },
+    );
+};
+
+
+
+
+
+
+ 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 @@ + + +023.pl + + + + +
+
+
+                                   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'],
+    );
+};
+
+
+
+
+
+
+ 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 @@ + + +024.pl + + + + +
+
+                                   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' });
+
+
+
+
+
+ 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 @@ + + +025.pl + + + + +
+
+
+
+                                   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' });
+
+
+
+
+
+
+
+ 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 @@ + + +026 + + + + +
+
+
+
+
+
+
+
+                                   Lifecycles
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026b + + + + +
+
+
+
+
+
+
+
+                                   Lifecycles
+    
+     · this is what determines what happens when ->get is called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026c + + + + +
+
+
+
+
+
+
+
+                                   Lifecycles
+    
+     · this is what determines what happens when ->get is called
+     · by default, each call to ->get creates a new object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026z + + + + +
+
+
+
+
+
+
+
+                                   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
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027.pl + + + + +
                                  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');
+
+
+
+ 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 @@ + + +028 + + + + +
+
+
+
+
+
+
+
+                                 Best Practices
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028b + + + + +
+
+
+
+
+
+
+
+                                 Best Practices
+    
+     · only use containers during initialization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028c + + + + +
+
+
+
+
+
+
+
+                                 Best Practices
+    
+     · only use containers during initialization
+       · factories
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028d + + + + +
+
+
+
+
+
+
+
+                                 Best Practices
+    
+     · only use containers during initialization
+       · factories
+     · avoid unnecessary subcontainers
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028z + + + + +
+
+
+
+
+
+
+
+                                 Best Practices
+    
+     · only use containers during initialization
+       · factories
+     · avoid unnecessary subcontainers
+     · container classes
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +029.pl + + + + +
+
+
+
+
+
+package MyApp::Container;
+use Moose;
+extends 'Bread::Board::Container';
+
+sub BUILD {
+    container $self => as {
+        ...;
+    };
+}
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030.pl + + + + +
+
+
+
+
+
+
+
+
+container SomethingElse => as {
+    container MyApp::Container->new;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +031 + + + + +
+
+
+
+
+
+
+
+                                    Typemaps
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +031b + + + + +
+
+
+
+
+
+
+
+                                    Typemaps
+    
+     · defines a mapping from a class_type to a service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +031c + + + + +
+
+
+
+
+
+
+
+                                    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');
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +031z + + + + +
+
+
+
+
+
+
+
+                                    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
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +032.pl + + + + +
+
+
+
+
+
+
+
+package Model
+use Moose;
+has logger => (is => 'ro', isa => 'Logger', required => 1);
+
+package Logger;
+use Moose;
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +033.pl + + + + +
+
+
+
+
+
+
+
+my $c = container MyApp => as {
+    typemap Logger => infer;
+    typemap Model => infer;
+};
+$c->resolve(type => 'Model')->logger; # a valid logger object
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +034 + + + + +
+
+
+
+
+
+
+
+                                    Typemaps
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +034b + + + + +
+
+
+
+
+
+
+
+                                    Typemaps
+    
+     · required attributes are automatically inferred, becoming either
+       dependencies (on types) or parameters (if the type doesn't exist
+       in the typemap)
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +034z + + + + +
+
+
+
+
+
+
+
+                                    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
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +035.pl + + + + +
                             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);
+
+
+
+ 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 @@ + + +036 + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036b + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+     · services are declared just by defining attributes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036c + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+     · services are declared just by defining attributes
+     · attribute accessors resolve the service if no value is set
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036d + + + + +
+
+
+
+
+
+
+
+                             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
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036z + + + + +
+
+
+
+
+
+
+
+                             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
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037 + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037b + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+     · typemaps are much simplified
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037c + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+     · typemaps are much simplified
+     · attributes with class_type constraints automatically get a typemap
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037z + + + + +
+
+
+
+
+
+
+
+                             Bread::Board::Declare
+    
+     · typemaps are much simplified
+     · attributes with class_type constraints automatically get a typemap
+     · «infer => 1» infers as many dependencies as possible
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +038.pl + + + + +
+
+
+                       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'],
+    );
+};
+
+
+
+
+
+
+ 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 @@ + + +039.pl + + + + +
+
+
+
+
+
+                         Catalyst::Plugin::Bread::Board
+
+package MyApp;
+use Catalyst 'Bread::Board';
+
+__PACKAGE__->config(
+    'Plugin::Bread::Board' => {
+        container => MyApp::Container->new,
+    }
+);
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +040.pl + + + + +
+
+                                       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';
+};
+
+
+
+
+
+
+ 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 @@ + + +041 + + + + +
+
+
+
+
+
+
+
+                                   Questions?
+
+                    https://metacpan.org/module/Bread::Board
+               https://metacpan.org/module/Bread::Board::Declare
+                          https://github.com/stevan/OX
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +Dependency Injection with Bread::Board + + + + + +

Use SPACEBAR to peruse the slides or click one to start...

+

Dependency Injection with Bread::Board

+ +

This presentation was generated by Vroom. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +

+ 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 @@ + + +001 + + + + +
+
+
+
+
+
+                           Extending Moose
+
+                by Jesse Luehrs (doy at tozt dot net)
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002 + + + + +
+
+
+
+
+
+
+                             motivation
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +003 + + + + +
+
+
+
+
+        moose
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +003b + + + + +
+
+
+
+
+        moose
+        
+        great class builder
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +003z + + + + +
+
+
+
+
+        moose
+        
+        great class builder
+        
+        lots of beginner info available
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +004 + + + + +
+
+
+
+
+
+
+        using only the basic features doesn't gain you much
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005.pl + + + + +
+
+
+
+
+
+    package Foo;
+    use base qw(Class::Accessor);
+    __PACKAGE__->mk_accessors('bar');
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +006.pl + + + + +
+
+
+
+
+
+    package Foo;
+    use Moose;
+    has bar => (is => 'ro');
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007.pl + + + + +
+
+
+
+
+    but...
+    
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007z.pl + + + + +
+
+
+
+
+    but...
+    
+    package Foo;
+    use Class::Accessor 'antlers';
+    has bar => (is => 'ro');
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008 + + + + +
+
+
+
+
+        moose gives you more than this
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008b + + + + +
+
+
+
+
+        moose gives you more than this
+        
+        * builders
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008c + + + + +
+
+
+
+
+        moose gives you more than this
+        
+        * builders
+        * delegation
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008d + + + + +
+
+
+
+
+        moose gives you more than this
+        
+        * builders
+        * delegation
+        * roles
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008z + + + + +
+
+
+
+
+        moose gives you more than this
+        
+        * builders
+        * delegation
+        * roles
+        * etc...
+
+
+
+
+
+
+
+
+ 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 @@ + + +009 + + + + +
+
+
+
+
+
+
+        but the real power of moose is in extensibility
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +010 + + + + +
+
+        typical object systems are defined in terms of, well, object systems
+        
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +010b + + + + +
+
+        typical object systems are defined in terms of, well, object systems
+        
+        has input_file => (
+           is       => 'ro',
+           isa      => File,
+           coerce   => 1,
+           required => 1,
+        );
+        
+
+
+
+
+
+
+
+
+ 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 @@ + + +010c + + + + +
+
+        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?
+        
+
+
+
+
+
+
+ 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 @@ + + +010z + + + + +
+
+        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';
+
+
+
+
+
+ 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 @@ + + +011 + + + + +
+
+
+
+
+        code should be written with the intent of communicating with *humans*
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011b + + + + +
+
+
+
+
+        code should be written with the intent of communicating with *humans*
+        
+        computers are great at figuring out the details on their own
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011z + + + + +
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +012 + + + + +
+
+
+
+
+
+
+        this has different levels:
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +013 + + + + +
+
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +014 + + + + +
+
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015 + + + + +
+
+
+
+
+
+        but what we'd really like is:
+        
+        a user has a name, and you can ask if its password is correct
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +016 + + + + +
+
+
+
+
+
+
+        moose can give us this too
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +017 + + + + +
+
+
+
+
+
+                               the mop
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +017z + + + + +
+
+
+
+
+
+                               the mop
+        
+                       (meta object protocol)
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +018 + + + + +
+
+
+
+
+
+
+        models classes as objects
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019 + + + + +
+
+
+
+        every class is represented by a metaclass
+        
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019b + + + + +
+
+
+
+        every class is represented by a metaclass
+        
+        a normal perl object of the class Moose::Meta::Class
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019c + + + + +
+
+
+
+        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)
+        
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019z + + + + +
+
+
+
+        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)
+
+
+
+
+
+
+
+
+ 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 @@ + + +020 + + + + +
+
+
+
+
+
+
+                         Moose::Meta::Class
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +021 + + + + +
+
+
+
+
+
+
+        access these objects through Class->meta (a class method installed by "use Moose")
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022 + + + + +
+
+
+
+
+        class information is stored and manipulated through these objects
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022b + + + + +
+
+
+
+
+        class information is stored and manipulated through these objects
+        
+        * "@ISA = ('Foo')"     -> "$meta->superclasses('Foo')"
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022c + + + + +
+
+
+
+
+        class information is stored and manipulated through these objects
+        
+        * "@ISA = ('Foo')"     -> "$meta->superclasses('Foo')"
+        * "*foo = sub { ... }" -> "$meta->add_method(foo => sub { ... })"
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022z + + + + +
+
+
+
+
+        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')"
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +023 + + + + +
+
+
+
+
+        also provides informational methods
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +023b + + + + +
+
+
+
+
+        also provides informational methods
+        
+        * $meta->class_precedence_list
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +023c + + + + +
+
+
+
+
+        also provides informational methods
+        
+        * $meta->class_precedence_list
+        * $meta->has_method('foo')
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +023z + + + + +
+
+
+
+
+        also provides informational methods
+        
+        * $meta->class_precedence_list
+        * $meta->has_method('foo')
+        * $meta->does_role('Role')
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +024 + + + + +
+
+
+
+
+        and provides other functionality specific to the mop
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +024b + + + + +
+
+
+
+
+        and provides other functionality specific to the mop
+        
+        * $meta->make_immutable
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +024c + + + + +
+
+
+
+
+        and provides other functionality specific to the mop
+        
+        * $meta->make_immutable
+        * $meta->new_object
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +024z + + + + +
+
+
+
+
+        and provides other functionality specific to the mop
+        
+        * $meta->make_immutable
+        * $meta->new_object
+        * Moose::Meta::Class->create_anon_class
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +025 + + + + +
+
+
+
+
+
+
+                       Moose::Meta::Attribute
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026 + + + + +
+
+
+
+
+        accessed through $meta->get_attribute, etc
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026b + + + + +
+
+
+
+
+        accessed through $meta->get_attribute, etc
+        
+        stores data associated with an object
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026z + + + + +
+
+
+
+
+        accessed through $meta->get_attribute, etc
+        
+        stores data associated with an object
+        
+        also handles installing methods associated with accessing that data
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027 + + + + +
+
+
+
+
+
+        informational methods:
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027b + + + + +
+
+
+
+
+
+        informational methods:
+        
+        * $meta_attr->get_read_method
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027z + + + + +
+
+
+
+
+
+        informational methods:
+        
+        * $meta_attr->get_read_method
+        * $meta_attr->type_constraint
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028 + + + + +
+
+
+
+
+
+        accessing data handled by the attribute
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028z + + + + +
+
+
+
+
+
+        accessing data handled by the attribute
+        
+        $meta_attr->get_value($obj)
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +029 + + + + +
+
+
+
+
+
+
+                         Moose::Meta::Method
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030 + + + + +
+
+
+
+        accessed through $meta->get_method, etc
+        
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030b + + + + +
+
+
+
+        accessed through $meta->get_method, etc
+        
+        represents a method associated with a class
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030c + + + + +
+
+
+
+        accessed through $meta->get_method, etc
+        
+        represents a method associated with a class
+        
+        these are typically introspected from the symbol table, not created explicitly
+        
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030z + + + + +
+
+
+
+        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
+
+
+
+
+
+
+
+
+ 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 @@ + + +031 + + + + +
+
+
+
+
+
+
+        so how does this all work?
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +032 + + + + +
+
+
+
+
+
+
+                           metacircularity
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +033 + + + + +
+
+
+
+
+        metaclasses are instances of the class Moose::Meta::Class
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +033b + + + + +
+
+
+
+
+        metaclasses are instances of the class Moose::Meta::Class
+        
+        but Moose::Meta::Class is itself a class
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +033z + + + + +
+
+
+
+
+        metaclasses are instances of the class Moose::Meta::Class
+        
+        but Moose::Meta::Class is itself a class
+        
+        so it must have a metaclass
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +034 + + + + +
+
+
+
+
+
+
+        this is accomplished by two tricks
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +035 + + + + +
+
+
+
+
+
+        compiler bootstrapping
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +035z + + + + +
+
+
+
+
+
+        compiler bootstrapping
+        
+        write a basic version first, replace it with the actual version once the structure is in place
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036 + + + + +
+
+
+
+
+
+        Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036z + + + + +
+
+
+
+
+
+        Moose::Meta::Class has a metaclass, but it's also a Moose::Meta::Class
+        
+        so Class->meta->meta == Class->meta
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037 + + + + +
+
+
+
+
+
+
+        but this is mostly irrelevant
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +038 + + + + +
+
+
+
+
+
+        the idea to take away is that moose is built on top of moose
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +038z + + + + +
+
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +039 + + + + +
+
+
+
+
+
+
+        so we have this foundation, but how can we make this easy to use?
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +040 + + + + +
+
+
+
+
+
+
+                           Moose::Exporter
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +041 + + + + +
+
+
+
+
+
+        we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro'))
+        
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +041z + + + + +
+
+
+
+
+
+        we have __PACKAGE__->meta->add_attribute(foo => (is => 'ro'))
+        
+        but we'd like "has foo => (is => 'ro')"
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042 + + + + +
+
+
+
+
+        Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042b + + + + +
+
+
+
+
+        Moose::Exporter is a wrapper around Sub::Exporter providing moose-specific functionality
+        
+        can curry the metaclass into helper functions
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042z + + + + +
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043 + + + + +
+
+
+
+
+        Moose itself uses Moose::Exporter
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043b + + + + +
+
+
+
+
+        Moose itself uses Moose::Exporter
+        
+        'has' is a thin wrapper around __PACKAGE__->meta->add_attribute
+        
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043z + + + + +
+
+
+
+
+        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
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +044 + + + + +
+
+
+
+
+
+
+        so the key here is that all of these metaclasses can be customized, and Moose::Exporter can wrap those customizations to make them pretty
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +045 + + + + +
+
+
+
+
+
+
+        basic extensions don't even need to alter the metaclass
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +046.pl + + + + +
    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,
+        );
+    }
+
+ 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 @@ + + +047.pl + + + + +
+
+
+
+
+    package Foo;
+    use Moose;
+    use FileAttributes;
+    
+    has_file 'foo';
+    has_file 'bar' => (required => 1);
+
+
+
+
+
+
+
+
+ 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 @@ + + +048 + + + + +
+
+
+
+
+
+
+        but altering metaclasses can provide more powerful abstractions
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +049.pl + + + + +
+    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);
+    };
+
+
+
+
+
+ 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 @@ + + +050.pl + + + + +
    and make it pretty
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +050z.pl + + + + +
    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
+            ),
+        );
+    }
+
+ 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 @@ + + +051.pl + + + + +
+
+
+
+    package Foo;
+    use Moose;
+    use AtomicMethod;
+    
+    atomic_method foo => sub {
+        warn "in foo\n";
+    };
+
+
+
+
+
+
+
+
+ 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 @@ + + +052 + + + + +
+
+
+
+
+
+
+        combining metaclass alterations can be even more powerful
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +053.pl + + + + +
+
+
+
+
+
+
+    package Command::Role::Method;
+    use Moose::Role;
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +054.pl + + + + +
    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
+             : ();
+    }
+
+ 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 @@ + + +055.pl + + + + +
    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
+            ),
+        );
+    }
+
+ 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 @@ + + +056.pl + + + + +
+
+
+
+
+    package Foo;
+    use Moose;
+    use Command;
+    
+    command bar => sub { ... };
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +057.pl + + + + +
+    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;
+        }
+    }
+
+
+
+
+
+ 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 @@ + + +058 + + + + +
+
+
+
+
+
+
+        for larger projects, providing a custom exporter can simplify things greatly
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +059.pl + + + + +
    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;
+    }
+
+ 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 @@ + + +060 + + + + +
+
+
+
+
+
+
+        the positive side
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +061 + + + + +
+
+
+
+
+        these things are easily packaged up into standalone modules
+        
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +061b + + + + +
+
+
+
+
+        these things are easily packaged up into standalone modules
+        
+        * MooseX::FileAttributes
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +061c + + + + +
+
+
+
+
+        these things are easily packaged up into standalone modules
+        
+        * MooseX::FileAttributes
+        * MooseX::TransactionalMethods
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +061d + + + + +
+
+
+
+
+        these things are easily packaged up into standalone modules
+        
+        * MooseX::FileAttributes
+        * MooseX::TransactionalMethods
+        * IM::Engine::Plugin::Commands
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +061z + + + + +
+
+
+
+
+        these things are easily packaged up into standalone modules
+        
+        * MooseX::FileAttributes
+        * MooseX::TransactionalMethods
+        * IM::Engine::Plugin::Commands
+        * Blawd::OO, TAEB::OO, etc...
+
+
+
+
+
+
+
+
+ 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 @@ + + +062 + + + + +
+
+
+
+
+
+
+                           any questions?
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +Extending Moose + + + + + +

Use SPACEBAR to peruse the slides or click one to start...

+

Extending Moose

+ +

This presentation was generated by Vroom. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +

+ 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 @@ + + +001 + + + + +
+
+
+
+
+
+
+
+
+
+                                       OX
+                    The hardest working two letters in Perl
+
+                       Jesse Luehrs, Infinity Interactive
+
+                          http://github.com/stevan/OX/
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002 + + + + +
+
+
+
+
+
+
+
+
+
+                                    history
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002b + + + + +
+
+
+
+
+
+
+
+
+
+                                    history
+    
+    * custom app-specific stuff
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002c + + + + +
+
+
+
+
+
+
+
+
+
+                                    history
+    
+    * custom app-specific stuff
+    * CGI::Application
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002d + + + + +
+
+
+
+
+
+
+
+
+
+                                    history
+    
+    * custom app-specific stuff
+    * CGI::Application
+    * Catalyst
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +002z + + + + +
+
+
+
+
+
+
+
+
+
+                                    history
+    
+    * custom app-specific stuff
+    * CGI::Application
+    * Catalyst
+    * Plack
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +003 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+                          OX - the web anti-framework
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +004 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+                                     Stevan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005 + + + + +
+
+
+
+
+
+
+
+
+
+                                  what is OX?
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005b + + + + +
+
+
+
+
+
+
+
+
+
+                                  what is OX?
+    
+    * Bread::Board
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005c + + + + +
+
+
+
+
+
+
+
+
+
+                                  what is OX?
+    
+    * Bread::Board
+    * Path::Router
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005d + + + + +
+
+
+
+
+
+
+
+
+
+                                  what is OX?
+    
+    * Bread::Board
+    * Path::Router
+    * Plack
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +005z + + + + +
+
+
+
+
+
+
+
+
+
+                                  what is OX?
+    
+    * Bread::Board
+    * Path::Router
+    * Plack
+    * EXPERIMENTAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +006.pl + + + + +
+
+
+
+
+    # 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;
+
+
+
+
+
+
+
+
+ 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 @@ + + +007 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    Bread::Board
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +007z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    Bread::Board
+    control your object's construction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008 + + + + +
+
+
+
+
+
+
+
+
+
+
+    Bread::Board has containers, containers contain services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008b + + + + +
+
+
+
+
+
+
+
+
+
+
+    Bread::Board has containers, containers contain services
+    an OX application is a Bread::Board container
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +008z + + + + +
+
+
+
+
+
+
+
+
+
+
+    Bread::Board has containers, containers contain services
+    an OX application is a Bread::Board container
+    all application objects are services in the container
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +009 + + + + +
+
+
+
+
+
+
+
+
+
+
+    services can depend on other services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +009b + + + + +
+
+
+
+
+
+
+
+
+
+
+    services can depend on other services
+    dependencies are resolved first
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +009z + + + + +
+
+
+
+
+
+
+
+
+
+
+    services can depend on other services
+    dependencies are resolved first
+    passed as constructor parameters to the requested service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +010 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    at minimum, the router and the app coderef itself are services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +011.pl + + + + +
+    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;
+
+
+
+
+
+ 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 @@ + + +012.pl + + + + +
+
+    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;
+
+
+
+
+
+
+ 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 @@ + + +013 + + + + +
+
+
+
+
+
+
+
+
+
+
+    Path::Router
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +013b + + + + +
+
+
+
+
+
+
+
+
+
+
+    Path::Router
+    translate incoming urls into structured data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +013z + + + + +
+
+
+
+
+
+
+
+
+
+
+    Path::Router
+    translate incoming urls into structured data
+    also translate structured data into urls
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +014.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+    route '/set/:num' => 'root.set', (
+        num => { isa => 'Int' },
+    );
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    /set/23 -> { num => 23 }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +015z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    /set/23 -> { num => 23 }
+    not just the hashref, but also the code to call for this path
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +016 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    bidirectional
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +017.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    $router->uri_for({num => 23}); # '/set/23'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +018 + + + + +
+
+
+
+
+
+
+
+
+
+
+    this translation is controlled by OX, and is pluggable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +018b + + + + +
+
+
+
+
+
+
+
+
+
+
+    this translation is controlled by OX, and is pluggable
+    already seen examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +018z + + + + +
+
+
+
+
+
+
+
+
+
+
+    this translation is controlled by OX, and is pluggable
+    already seen examples
+    route '/' => sub { ... }
+    route '/' => 'root.index'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +019.pl + + + + +
+
+
+
+
+
+
+
+
+
+    has root => (is => 'ro', isa => 'Controller');
+    
+    router ['HTTPMethod'] => as {
+        route '/' => 'root';
+    }, (root => 'root');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +020 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    GET request for '/' will call Controller::get
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +020z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    GET request for '/' will call Controller::get
+    POST request for '/' will call Controller::post
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +021 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    this is just the sugar layer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +022.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+    package App;
+    use OX;
+    
+    sub configure_router { ... }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +023 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    or, you can replace the router entirely
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +024.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    router 'My::Custom::Router::Class';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +025 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    Plack
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026 + + + + +
+
+
+
+
+
+
+
+
+
+
+    OX applications provide the Plack::Component api
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +026z + + + + +
+
+
+
+
+
+
+
+
+
+
+    OX applications provide the Plack::Component api
+    ->prepare_app
+    ->call
+    ->to_app
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027 + + + + +
+
+
+
+
+
+
+
+
+
+
+    two types of middleware
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027b + + + + +
+
+
+
+
+
+
+
+
+
+
+    two types of middleware
+    deployment (Stacktrace, ReverseProxy)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +027z + + + + +
+
+
+
+
+
+
+
+
+
+
+    two types of middleware
+    deployment (Stacktrace, ReverseProxy)
+    app-specific (Session)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +028 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    your application class should be able to declare app-specific middleware
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +029.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+    router as {
+        wrap 'Plack::Middleware::Session';
+        route '/' => ...;
+    };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +030.pl + + + + +
+
+
+
+
+
+
+    has session_store => (
+        is    => 'ro',
+        isa   => 'Str',
+        value => 'File',
+    );
+    
+    router as {
+        wrap 'Plack::Middleware::Session' => (
+            store => 'session_store',
+        );
+        route '/' => ...;
+    };
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +031 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    again, this is just the sugar layer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +032.pl + + + + +
+
+
+
+
+
+
+    package App;
+    use Moose;
+    extends 'OX::Application';
+    
+    sub configure_router {
+        ...
+    }
+    
+    sub app_from_router {
+        ...
+    }
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +033.pl + + + + +
+
+
+    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 {
+        ...
+    }
+
+
+
+
+
+
+
+ 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 @@ + + +034 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    benefits of OX
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +035 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    reuse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +035z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    reuse
+    no wrapper classes required
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +036.pl + + + + +
+
+
+
+
+
+
+
+
+    package App;
+    use OX;
+    
+    has model => (is => 'ro', isa => 'KiokuX::Model');
+    has view  => (is => 'ro', isa => 'Template');
+    
+    ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +037.pl + + + + +
+
+
+
+    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' },
+    );
+    
+    ...
+
+
+
+
+
+
+
+ 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 @@ + + +038 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    application classes are decoupled, and can be used independently
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +039.pl + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    App->new->model
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +040 + + + + +
+
+
+
+
+
+
+
+
+
+
+    get the model object exactly as it would be initialized within the app
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +040b + + + + +
+
+
+
+
+
+
+
+
+
+
+    get the model object exactly as it would be initialized within the app
+    except without initializing the app
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +040z + + + + +
+
+
+
+
+
+
+
+
+
+
+    get the model object exactly as it would be initialized within the app
+    except without initializing the app
+    very useful for standalone scripts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +041 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    App->new(dsn => 'dbi:SQLite::memory:')->to_app
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042 + + + + +
+
+
+
+
+
+
+
+
+
+
+    override specific bits of the application at initialization time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042b + + + + +
+
+
+
+
+
+
+
+
+
+
+    override specific bits of the application at initialization time
+    makes testing very easy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +042z + + + + +
+
+
+
+
+
+
+
+
+
+
+    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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043 + + + + +
+
+
+
+
+
+
+
+
+
+
+    the entire structure is just building on existing technology
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043b + + + + +
+
+
+
+
+
+
+
+
+
+
+    the entire structure is just building on existing technology
+    applications can use roles and inheritance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043c + + + + +
+
+
+
+
+
+
+
+
+
+
+    the entire structure is just building on existing technology
+    applications can use roles and inheritance
+    middleware just works
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +043z + + + + +
+
+
+
+
+
+
+
+
+
+
+    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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +044 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    TODO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +045 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    nested applications need work
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +045z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    nested applications need work
+    in particular, how can services be shared?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +046 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    bread::board subcontainers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +046z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    bread::board subcontainers
+    need a syntax for this
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +047 + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    more extensible routebuilders
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +047z + + + + +
+
+
+
+
+
+
+
+
+
+
+
+    more extensible routebuilders
+    want a way to let the controller object control the dispatching
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +048 + + + + +
+
+
+
+
+
+
+
+
+
+
+    cleaner underlying foundation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +048b + + + + +
+
+
+
+
+
+
+
+
+
+
+    cleaner underlying foundation
+    more ways to customize the router
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +048z + + + + +
+
+
+
+
+
+
+
+
+
+
+    cleaner underlying foundation
+    more ways to customize the router
+    more ways to customize the container
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +049 + + + + +
+
+
+
+
+
+
+
+
+
+
+                                 Any questions?
+
+                          http://github.com/stevan/OX/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 @@ + + +OX - The hardest working two letters in Perl + + + + + +

Use SPACEBAR to peruse the slides or click one to start...

+

OX - The hardest working two letters in Perl

+ +

This presentation was generated by Vroom. Use <SPACE> key to go +forward and <BACKSPACE> to go backwards. +

+ 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/ -- cgit v1.2.3-54-g00ecf