SlideShare a Scribd company logo
1 of 19
Download to read offline
Exporter::Proxy



Splitting up modules to help your sanity.


          Steven Lembark
        Workhorse Computing
Stuck in Lodi Again
●   We've all been there: the 4000­line module.
●   It began small enough... then it grew.
●   Canned­query modules are classics for this:
    ●   In the beginning was “userid”, and it was good, enough.
    ●   Then it was split into get_userid/set_userid.
    ●   Then it branched into get_dept_userid, 
        get_general_userid and set_*. 
●   That was then, your cleanup is now.
Welcome to the Machine
●   You have to clean up the module.
●   You need to split the thing into usable chunks.
    ●   Separating out namespaces.
    ●   Keeping shared variables in a reasonable place.
    ●   Keeping utility subs out of the way.
    ●   By tomorrow.
        In parallel universes, in constant time.
This is Perl, however.
●   So you will practice True Lazyness (c). 
●   This means doing it once.
●   Doing it right.
●   And never having to do it again.
Lazyness is a virtue
●   Exporting in Perl should be easy, but Exporter is 
    complicated (and error prone).
●   Breaking up large modules into manageable chunks 
    often takes too much work.
●   Both of these should be easy.
Un­lazy Shared Variables.
●   Exporter allows sharing variables.
●   If you inherit from it.
●   If you keep proper track of EXPORT_OK, 
    EXPORT, EXPORT_TAGS.
●   If, hopefully, @foo never changes to %foo.
●   There has to be a better way...
False Lazyness:
●   Break the module up by function,  the names don't 
    immediately collide: Lookup::userid,  Modify::userid
●   But, you can't inherit both classes without collisions.
●   You could try Lookup::Dept::userid and 
    Modify::Dept::userid.
    ●   But do you really want to see:
        $qryobj->Lookup::Dept::userid( ... );
        Let alone type it?
Un­Lazy Top­Half Modules
●   Another way to split up the modules is a single God 
    Object dispatcher that “figures out” how to dispatch 
    into the various pieces of the original module. 
●   This ends up being either a un­maintainable if­
    block, an un­readable n­ary ternary op, or the 
    Switch From Hell (tm).
●   The problem is that the caller knows what they 
    want: expose them to the decisions and let them 
    make the proper one.
Exporter::Proxy
●   This is Perl, there is a lazy way.
●   E::P simplifies you work by:
    ●   Exporting symbols.
    ●   Installing an import sub to export the symbols.
    ●   Optionally installing a dispatch sub.
●   This allows you to split your modules into layers:
    ●   A top­half dispatcher that combines the moduels.
    ●   The bottom­half modules that actually do the work.
    ●   Common shared variables, all stored in one place.
“The simplest interface is none at all”
●   Instead of having to define a set of variables for your 
    set of variables, just:
    use Exporter::Proxy qw( verbose debug foobar );
●   Whatever names you provide are exported as 
    symbols via Symbol:
    my $source = qualify_to_ref $_, $source;
    my $install = qualify_to_ref $_, $caller;
    *$install   = *$source;

●   $verbose, &verbose, @verbose, %verbose, all you 
    have to export is “verbose”.
Lazy Dispatcher
●   These look pretty much the same: decide where the 
    call goes, send it there, and get out of the way.
●   This is done in Exporter::Proxy with the “dispatch=” 
    argument.
●   The dispatcher is exported by default.
●   Each one dispatches calls within its own package:
    my $name    = splice @_, 1, 1;
    my $dest    = $package->can( $name )
    or croak “$package cannot '$name'”;

    goto &$dest;
Splitting Up The Interface
●   You've probably witnessed *NIX device drivers .
●   The top half validates and dispatches the call, the 
    bottom half just does things.
●   The top half doesn't care what does on, it just sends 
    things where they belong.
●   The bottom half doesn't care why it does things, it 
    just does them.
Breaking Up A Module
●   You can usually break the combined interface up 
    into functional groups:
    ●   “modify” vs. “lookup”
    ●   “department” vs. “office” vs. “location”.
    ●   “Taxid”, “GenBank”, “Medline”, “MeSH”.
●   You can also combine any shared variables into a 
    single module that exports them as needed.
Looking At A Query Module
●   “modify” and “lookup” are probably good divisions.
●   The SQL for canned queries is probably sharable. 
●   The query methods don't care who their caller is.
●   The dispatcher doesn't care why the methods were 
    called, it just has to hand back the data.
●   Code something like:
      $query->lookup( department => @argz );
      $query->modify( department => @argz );
●   Is reasonably mnemonic and easily extended.
Bottom Half Does the Work.
●   The bottom half implements methods for specific 
    tasks and exports a single dispatcher for them.
●   Break the module up into Query::Lookup, 
    Query::Modify, Query::Shared.
●   Lookup & Modify install a dispatcher:
      use Exporter::Proxy qw( dispatch=lookup );
      use Exporter::Proxy qw( dispatch=query );
●   They pull in shared content by Using Query::Shared:
      package Query::Modify;
      use Query::Shared qw( modify_dml ); # SQL hash
The Public Interface is Truly Lazy
●   Bottom halves export their dispatchers: just collect 
    them together into a single API.
    package Query;

    use Query::Lookup;
    use Query::Modify;
    use Query::Shared qw( verbose );

    sub verbose { @_ ? $verbose = shift : $verbose }

    42
    __END__

●   The Top Half is DUMB: there are no decisions here, 
    no special cases, no edge cases.
What the Caller Sees
●   Anyone using “Query” just knows that its API 
    includes “lookup”, “modify”, and “verbose”.
●   The methods take a first argument of what to lookup 
    or modify, and whatever arguments it needs.
●   They don't have to know about the bottom­half, 
    shared variables, or utility sub's that aren't exported 
    by the bottom­half modules into the API.
●   This is what makes the Top Half dumb: the caller 
    makes their own decisions on what to call.
Lazy Growth
●   Re­factoring the interface into subject areas is also 
    straightforward:
    ●   Add new modules “department”, “office”, “frobnicate”.
    ●   Each has a mnemonic dispatcher, say, “dept”, “office”, 
        and “frob”.
    ●   They implement whatever methods describe the action.
    ●   They can share the existing SQL or define their own.
    ●   The caller uses, say,
           $query->dept( id => $dept_name );
Summary
●   True Lazyness is a virtue.
●   Dispatching interfaces offer a simple way to 
    segregate the classes.
●   Top­half classes can implement mnemonic API's.
●   Bottom duty can be bearable with Exporter::Proxy.

More Related Content

What's hot

Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureSander Mak (@Sander_Mak)
 
Flying under the radar
Flying under the radarFlying under the radar
Flying under the radarMark Baker
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to JavascriptAmit Tyagi
 
How do i - create a native interface
How do i -  create a native interfaceHow do i -  create a native interface
How do i - create a native interfaceShai Almog
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScriptT11 Sessions
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript BasicsMindfire Solutions
 
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...Edureka!
 
JavaScript - Chapter 5 - Operators
 JavaScript - Chapter 5 - Operators JavaScript - Chapter 5 - Operators
JavaScript - Chapter 5 - OperatorsWebStackAcademy
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the BasicsMichael Koby
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to JavascriptAnjan Banda
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPCiaranMcNulty
 
Testing untestable code - phpday
Testing untestable code - phpdayTesting untestable code - phpday
Testing untestable code - phpdayStephan Hochdörfer
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.xRyan Szrama
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-CKazunobu Tasaka
 

What's hot (19)

Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the future
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 
Flying under the radar
Flying under the radarFlying under the radar
Flying under the radar
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
Javascript
JavascriptJavascript
Javascript
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
How do i - create a native interface
How do i -  create a native interfaceHow do i -  create a native interface
How do i - create a native interface
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript Basics
 
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
 
JavaScript - Chapter 5 - Operators
 JavaScript - Chapter 5 - Operators JavaScript - Chapter 5 - Operators
JavaScript - Chapter 5 - Operators
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHP
 
Testing untestable code - phpday
Testing untestable code - phpdayTesting untestable code - phpday
Testing untestable code - phpday
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.x
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-C
 

Viewers also liked

Investor Seminar in San Francisco March 7th, 2015
Investor Seminar in San Francisco March 7th, 2015Investor Seminar in San Francisco March 7th, 2015
Investor Seminar in San Francisco March 7th, 2015Joe Pryor
 
Perly Parallel Processing of Fixed Width Data Records
Perly Parallel Processing of Fixed Width Data RecordsPerly Parallel Processing of Fixed Width Data Records
Perly Parallel Processing of Fixed Width Data RecordsWorkhorse Computing
 
Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Our Friends the Utils: A highway traveled by wheels we didn't re-invent. Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Our Friends the Utils: A highway traveled by wheels we didn't re-invent. Workhorse Computing
 
Low and No cost real estate marketing plan for Enid Oklahoma
Low and No cost real estate marketing plan for Enid OklahomaLow and No cost real estate marketing plan for Enid Oklahoma
Low and No cost real estate marketing plan for Enid OklahomaJoe Pryor
 
Aligning seqeunces with W-curve and SQL.
Aligning seqeunces with W-curve and SQL.Aligning seqeunces with W-curve and SQL.
Aligning seqeunces with W-curve and SQL.Workhorse Computing
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
San Francisco Real Estate Investor Seminar June 14th 2014
San Francisco Real Estate Investor Seminar June 14th 2014San Francisco Real Estate Investor Seminar June 14th 2014
San Francisco Real Estate Investor Seminar June 14th 2014Joe Pryor
 
Real estate hacks for a successful business plan
Real estate hacks for a successful business planReal estate hacks for a successful business plan
Real estate hacks for a successful business planJoe Pryor
 
Object::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeObject::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeWorkhorse Computing
 
Investment webinar about Oklahoma City real estate investment
Investment webinar about Oklahoma City real estate investmentInvestment webinar about Oklahoma City real estate investment
Investment webinar about Oklahoma City real estate investmentJoe Pryor
 
2016 builder summit pp powerpoint
2016 builder summit pp powerpoint2016 builder summit pp powerpoint
2016 builder summit pp powerpointJoe Pryor
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 

Viewers also liked (16)

Investor Seminar in San Francisco March 7th, 2015
Investor Seminar in San Francisco March 7th, 2015Investor Seminar in San Francisco March 7th, 2015
Investor Seminar in San Francisco March 7th, 2015
 
A-Walk-on-the-W-Side
A-Walk-on-the-W-SideA-Walk-on-the-W-Side
A-Walk-on-the-W-Side
 
Perly Parallel Processing of Fixed Width Data Records
Perly Parallel Processing of Fixed Width Data RecordsPerly Parallel Processing of Fixed Width Data Records
Perly Parallel Processing of Fixed Width Data Records
 
Object Exercise
Object ExerciseObject Exercise
Object Exercise
 
Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Our Friends the Utils: A highway traveled by wheels we didn't re-invent. Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
 
Low and No cost real estate marketing plan for Enid Oklahoma
Low and No cost real estate marketing plan for Enid OklahomaLow and No cost real estate marketing plan for Enid Oklahoma
Low and No cost real estate marketing plan for Enid Oklahoma
 
Clustering Genes: W-curve + TSP
Clustering Genes: W-curve + TSPClustering Genes: W-curve + TSP
Clustering Genes: W-curve + TSP
 
Aligning seqeunces with W-curve and SQL.
Aligning seqeunces with W-curve and SQL.Aligning seqeunces with W-curve and SQL.
Aligning seqeunces with W-curve and SQL.
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
San Francisco Real Estate Investor Seminar June 14th 2014
San Francisco Real Estate Investor Seminar June 14th 2014San Francisco Real Estate Investor Seminar June 14th 2014
San Francisco Real Estate Investor Seminar June 14th 2014
 
Real estate hacks for a successful business plan
Real estate hacks for a successful business planReal estate hacks for a successful business plan
Real estate hacks for a successful business plan
 
Lazy Data Using Perl
Lazy Data Using PerlLazy Data Using Perl
Lazy Data Using Perl
 
Object::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeObject::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your Code
 
Investment webinar about Oklahoma City real estate investment
Investment webinar about Oklahoma City real estate investmentInvestment webinar about Oklahoma City real estate investment
Investment webinar about Oklahoma City real estate investment
 
2016 builder summit pp powerpoint
2016 builder summit pp powerpoint2016 builder summit pp powerpoint
2016 builder summit pp powerpoint
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 

Similar to Split Large Modules Easily with Exporter::Proxy

Getting big without getting fat, in perl
Getting big without getting fat, in perlGetting big without getting fat, in perl
Getting big without getting fat, in perlDean Hamstead
 
Learn To Code: Introduction to java
Learn To Code: Introduction to javaLearn To Code: Introduction to java
Learn To Code: Introduction to javaSadhanaParameswaran
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
(3) cpp procedural programming
(3) cpp procedural programming(3) cpp procedural programming
(3) cpp procedural programmingNico Ludwig
 
The State of the Veil Framework
The State of the Veil FrameworkThe State of the Veil Framework
The State of the Veil FrameworkVeilFramework
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James NelsonGWTcon
 
Extending CMS Made Simple
Extending CMS Made SimpleExtending CMS Made Simple
Extending CMS Made Simplecmsmssjg
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part IEugene Lazutkin
 
Groovy there's a docker in my application pipeline
Groovy there's a docker in my application pipelineGroovy there's a docker in my application pipeline
Groovy there's a docker in my application pipelineKris Buytaert
 
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert NETWAYS
 
Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)A K M Zahiduzzaman
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 
Create ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm packageCreate ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm packageAndrii Lundiak
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017Ayush Sharma
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programmingDhaval Dalal
 
Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrapdonnfelker
 
Nodejs web service for starters
Nodejs web service for startersNodejs web service for starters
Nodejs web service for startersBruce Li
 
Smart Client Development
Smart Client DevelopmentSmart Client Development
Smart Client DevelopmentTamir Khason
 

Similar to Split Large Modules Easily with Exporter::Proxy (20)

Getting big without getting fat, in perl
Getting big without getting fat, in perlGetting big without getting fat, in perl
Getting big without getting fat, in perl
 
Learn To Code: Introduction to java
Learn To Code: Introduction to javaLearn To Code: Introduction to java
Learn To Code: Introduction to java
 
Es build presentation
Es build presentationEs build presentation
Es build presentation
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
(3) cpp procedural programming
(3) cpp procedural programming(3) cpp procedural programming
(3) cpp procedural programming
 
The State of the Veil Framework
The State of the Veil FrameworkThe State of the Veil Framework
The State of the Veil Framework
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
Extending CMS Made Simple
Extending CMS Made SimpleExtending CMS Made Simple
Extending CMS Made Simple
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part I
 
Groovy there's a docker in my application pipeline
Groovy there's a docker in my application pipelineGroovy there's a docker in my application pipeline
Groovy there's a docker in my application pipeline
 
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert
OSMC 2017 | Groovy There is a Docker in my Dashing Pipeline by Kris Buytaert
 
Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
Create ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm packageCreate ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm package
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programming
 
Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrap
 
Nodejs web service for starters
Nodejs web service for startersNodejs web service for starters
Nodejs web service for starters
 
Smart Client Development
Smart Client DevelopmentSmart Client Development
Smart Client Development
 

More from Workhorse Computing

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Workhorse Computing
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 

More from Workhorse Computing (20)

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Smoking docker
Smoking dockerSmoking docker
Smoking docker
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 

Recently uploaded

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Recently uploaded (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Split Large Modules Easily with Exporter::Proxy

  • 1. Exporter::Proxy Splitting up modules to help your sanity. Steven Lembark Workhorse Computing
  • 2. Stuck in Lodi Again ● We've all been there: the 4000­line module. ● It began small enough... then it grew. ● Canned­query modules are classics for this: ● In the beginning was “userid”, and it was good, enough. ● Then it was split into get_userid/set_userid. ● Then it branched into get_dept_userid,  get_general_userid and set_*.  ● That was then, your cleanup is now.
  • 3. Welcome to the Machine ● You have to clean up the module. ● You need to split the thing into usable chunks. ● Separating out namespaces. ● Keeping shared variables in a reasonable place. ● Keeping utility subs out of the way. ● By tomorrow. In parallel universes, in constant time.
  • 4. This is Perl, however. ● So you will practice True Lazyness (c).  ● This means doing it once. ● Doing it right. ● And never having to do it again.
  • 5. Lazyness is a virtue ● Exporting in Perl should be easy, but Exporter is  complicated (and error prone). ● Breaking up large modules into manageable chunks  often takes too much work. ● Both of these should be easy.
  • 6. Un­lazy Shared Variables. ● Exporter allows sharing variables. ● If you inherit from it. ● If you keep proper track of EXPORT_OK,  EXPORT, EXPORT_TAGS. ● If, hopefully, @foo never changes to %foo. ● There has to be a better way...
  • 7. False Lazyness: ● Break the module up by function,  the names don't  immediately collide: Lookup::userid,  Modify::userid ● But, you can't inherit both classes without collisions. ● You could try Lookup::Dept::userid and  Modify::Dept::userid. ● But do you really want to see: $qryobj->Lookup::Dept::userid( ... ); Let alone type it?
  • 8. Un­Lazy Top­Half Modules ● Another way to split up the modules is a single God  Object dispatcher that “figures out” how to dispatch  into the various pieces of the original module.  ● This ends up being either a un­maintainable if­ block, an un­readable n­ary ternary op, or the  Switch From Hell (tm). ● The problem is that the caller knows what they  want: expose them to the decisions and let them  make the proper one.
  • 9. Exporter::Proxy ● This is Perl, there is a lazy way. ● E::P simplifies you work by: ● Exporting symbols. ● Installing an import sub to export the symbols. ● Optionally installing a dispatch sub. ● This allows you to split your modules into layers: ● A top­half dispatcher that combines the moduels. ● The bottom­half modules that actually do the work. ● Common shared variables, all stored in one place.
  • 10. “The simplest interface is none at all” ● Instead of having to define a set of variables for your  set of variables, just: use Exporter::Proxy qw( verbose debug foobar ); ● Whatever names you provide are exported as  symbols via Symbol: my $source = qualify_to_ref $_, $source; my $install = qualify_to_ref $_, $caller; *$install = *$source; ● $verbose, &verbose, @verbose, %verbose, all you  have to export is “verbose”.
  • 11. Lazy Dispatcher ● These look pretty much the same: decide where the  call goes, send it there, and get out of the way. ● This is done in Exporter::Proxy with the “dispatch=”  argument. ● The dispatcher is exported by default. ● Each one dispatches calls within its own package: my $name = splice @_, 1, 1; my $dest = $package->can( $name ) or croak “$package cannot '$name'”; goto &$dest;
  • 12. Splitting Up The Interface ● You've probably witnessed *NIX device drivers . ● The top half validates and dispatches the call, the  bottom half just does things. ● The top half doesn't care what does on, it just sends  things where they belong. ● The bottom half doesn't care why it does things, it  just does them.
  • 13. Breaking Up A Module ● You can usually break the combined interface up  into functional groups: ● “modify” vs. “lookup” ● “department” vs. “office” vs. “location”. ● “Taxid”, “GenBank”, “Medline”, “MeSH”. ● You can also combine any shared variables into a  single module that exports them as needed.
  • 14. Looking At A Query Module ● “modify” and “lookup” are probably good divisions. ● The SQL for canned queries is probably sharable.  ● The query methods don't care who their caller is. ● The dispatcher doesn't care why the methods were  called, it just has to hand back the data. ● Code something like: $query->lookup( department => @argz ); $query->modify( department => @argz ); ● Is reasonably mnemonic and easily extended.
  • 15. Bottom Half Does the Work. ● The bottom half implements methods for specific  tasks and exports a single dispatcher for them. ● Break the module up into Query::Lookup,  Query::Modify, Query::Shared. ● Lookup & Modify install a dispatcher: use Exporter::Proxy qw( dispatch=lookup ); use Exporter::Proxy qw( dispatch=query ); ● They pull in shared content by Using Query::Shared: package Query::Modify; use Query::Shared qw( modify_dml ); # SQL hash
  • 16. The Public Interface is Truly Lazy ● Bottom halves export their dispatchers: just collect  them together into a single API. package Query; use Query::Lookup; use Query::Modify; use Query::Shared qw( verbose ); sub verbose { @_ ? $verbose = shift : $verbose } 42 __END__ ● The Top Half is DUMB: there are no decisions here,  no special cases, no edge cases.
  • 17. What the Caller Sees ● Anyone using “Query” just knows that its API  includes “lookup”, “modify”, and “verbose”. ● The methods take a first argument of what to lookup  or modify, and whatever arguments it needs. ● They don't have to know about the bottom­half,  shared variables, or utility sub's that aren't exported  by the bottom­half modules into the API. ● This is what makes the Top Half dumb: the caller  makes their own decisions on what to call.
  • 18. Lazy Growth ● Re­factoring the interface into subject areas is also  straightforward: ● Add new modules “department”, “office”, “frobnicate”. ● Each has a mnemonic dispatcher, say, “dept”, “office”,  and “frob”. ● They implement whatever methods describe the action. ● They can share the existing SQL or define their own. ● The caller uses, say, $query->dept( id => $dept_name );
  • 19. Summary ● True Lazyness is a virtue. ● Dispatching interfaces offer a simple way to  segregate the classes. ● Top­half classes can implement mnemonic API's. ● Bottom duty can be bearable with Exporter::Proxy.