Adventures in
TclOOor, Here’s Some Tricks I’ve Been Up To
Donal Fellows
University of Manchester / Tcl Core
Team
Outline
 A Quick TclOO Refresher
 Support Class for REST
 Wrapping TDBC with ORM
 Extending TclOO with Annotations
 Where to go in the Future
2
Refresher
A Quick TclOO…
3
TclOO Refresher
 Object System
 Incorporated in 8.6, Package for 8.5
 Designed for
 Keeping Out of Your Way
 Being Tcl’ish and Dynamic
 Being Powerful and Extensible
 Key Features
 Single-Rooted Inheritance Hierarchy
 Classes are Objects and May be Extended
 Object’s Namespace contains Object’s Variables
 Class (Re-)Definition by Separate Command
4
The Anatomy Lesson
oo::object
Namespace
Method
Table
Mixin
List
Variables
NS Path
Commands
Instance
Method
Table
Mixin
List
Superclass List
oo::class
An object
has these
things…
A class also
has these,
which apply
to instances
Classes are objects
Objects are
made by
classes
You can subclass the class of
classes for custom construction 5
REST
Support Class for…
REpresentational State Transfer
 REST is Way of Doing Web Services
 Popular
 Easy to Use in Ad Hoc Way
 Strongly Leverages HTTP
 Verbs are GET, PUT, DELETE, POST, …
 Nouns are Resources with URLs
 View of Resources Determined by Content
Negotiation
7
Example…
 http://example.org/pizzas is a Pizza Parlor
 GET http://example.org/pizzas
 Returns Current List of Pizzas
 GET http://example.org/pizzas/123
 Returns Description of Pizza #123
 GET http://example.org/pizzas/123/pepperoni
 Returns Amount of Pepperoni on Pizza
8
Example… Updates
 PUT http://example.org/pizzas/123/pepperoni
 Sets Amount of Pepperoni on Pizza #123
 Idempotent
 POST http://example.org/pizzas
 Makes a New Pizza from Scratch
 Request document says what to make
 Redirects to Created Pizza
 DELETE http://example.org/pizzas/123
 Gets Rid of Pizza #123
 Idempotent
9
REST Class
 TclOO Class
 Wrapper for http package
 Models a Base Resource
 Methods for Each HTTP Verb
 Designed to be Subclassed!
 Some Production Use
 Testing Interface for Very Complex REST Service
 More than 35 Operations with non-fixed URLs
 Still Growing…
10
General Plan
oo::object
Service Instance Service InstanceService Instance
oo::class
REST
Specific Service
11
Code (Simplified)
methodDoRequest{
methodurl {type ""} {value ""}} {
for {setrs0} {$rs< 5} {incrrs} {
settok [http::geturl $url 
-method $method 
-type $type -query $value]
try {
if{[http::ncode $tok] > 399} {
# ERROR
setmsg [myExtractError $tok]
return -code error $msg
} elseif {[http::ncode $tok] > 299
||[http::ncode $tok]==201} {
# REDIRECT
try {
setlocation [dictget 
[http::meta $tok] Location]
} on error {} {
error"missing location!"
}
myOnRedirect $tok $location
} else{
# SUCCESS
return[http::data $tok]
}
} finally {
http::cleanup $tok
}
}
error"too many redirections!"
}
methodGETargs {
return [myDoRequest GET 
$base/[join $args"/"]]
}
12
Usage
oo::class create Service {
superclass REST
# … etc …
methodstatus {{status""}} {
if {$statuseq""} {
return[my GET status]
}
my PUT status text/plain $status
return
}
}
13
Bioscience
ServicesBioscience
ServicesBioscience
Services
What I Was Using This For
Workflow Server
Web
FrontEnd
Database Filesystem
Heliophysics
ServicesHeliophysics
ServicesHeliophysics
Services
Chemistry
ServicesChemistry
ServicesChemistry
Services
Workflow
Workflow Workflow
Taverna 2 Server
Taverna
Engine
Taverna
Engine
Taverna
EngineTesting
This Part
14
ORM
Wrapping TDBC with…
Object-Relational Mapping
 Objects are Natural Way to Model World
 Well, much of it…
 Relational Databases are Excellent at Managing
Data
 Build Links between Objects and Databases
 Many Languages Have Them
 Java, C#, Ruby, …
 Wanted to do in Tcl
 Leverage TclOO and TDBC
16
Data First or Objects First?
 Data First
 Data is already in the database
 How to introspect database’s structure
 How to represent naturally as objects
 Objects First
 Data is in objects
 How to construct database to store and restore
 My ORM Package is Data First
 Dynamic class construction!
17
Basic Class Plan
oo::object oo::class
Database Table
NamedRow AnonRow
Instance
makes
instance
subclass
18
CRM DB
Interaction Plan
Database
Table
NamedRow
Order
Descn CustI
D
DispID
Customer
FirstName Surname
Dispatch
ID House Street City
ID
ID
State
crmdb
orderorder#42
customer
dispatch
customer#7
dispatch#9
Introspects DB
Columns go to properties
Foreign keys make
inter-object links
Class per table
Instance per row
19
Example of Use
# Connect to Database with TDBC
setconn [tdbc::sqlite3::connection new"mydb.sqlite3"]
# Create all the classes holding the mapping
ORM::Databasecreatedb $conn
# Illustrate use by printing out all orders
db table order foreachordr {
puts"Order #[$ordr id]"
puts"Customer: [[$ordr customer] firstname]
[[$ordr customer] surname]"
puts"Address: [[$ordr dispatch] house]
[[$ordr dispatch] street]"
puts"Address: [[$ordr dispatch] city],
[[$ordr dispatch] state]"
puts"Description:nt[$ordr description]"
puts""
}
20
Annotations
Extending TclOO with…
What is an Annotation?
 Additional Arbitrary Metadata
 Attached to Class or Part of Class
 User-Defined Purpose
 Easy way to add information without doing big
changes to TclOO’s C implementation
 Uses from Other Languages
 Documentation
 Constraints
 Coupling to Container Frameworks
 Persistence, Web Apps, Management, …
22
Annotation Syntax
@SomeAnnotation -foo bar
oo::class createExample {
@AnotherAnnotation
variablex
@GuessWhatThisIs
constructor {} { … }
@HowAboutThis?
@More…
methodxyzzy {xy} { … }
}
# To read the annotations…
puts [infoclassannotation Example]
23
Types of Annotations
 Annotations Specify What They Attach To
 Classes
 Methods
 Any declaration…
 Examples
 @Description
 @Argument
 @Result
 @SideEffect
24
Declaring an Annotation
oo::class createAnnotation.Argument {
superclassAnnotation.Describe
variableannotationmethod 
argument
# Save what argument this applies to
constructor{type argNameargs} {
setargument $argName
next $type {*}$args
}
# How an annotation is introspected
methoddescribe{v {n""} {an""}} {
upvar 1 $vresult
if {[llength [infolevel 0]] == 3} {
lappendresult $method
return
}
if{$method ne $n} {
return
}
if{[llength [infolevel 0]] == 4} {
lappendresult $argument
return
} elseif {$argumenteq$a} {
setresult [join $annotation]
return -code break
}
}
}
25
Under the Hood
 Every Class has List of Annotations Applied to it
 Attaching to Classes
 Uses Standard Unknown Handler
 Rewrites oo::class Command
 Attaching to Declarations
 Rewrites Whole TclOO Declaration System
 Change Declaration
 Local Unknown Handler
 Adding Introspection
 Extra commands in [info class] via ensemble
26
Under the Hood
TclOO Package Annotation Package
oo::class
oo::define
[info class]
interceptor
interceptors
extensions
Annotation
Class
Annotation
Store
Meddleswithinternals
27
Future?
Where to go in the
Future of REST Class
 Contribute to Tcllib
 Needs More Features First
 Authentication Support
 Cookie Handling
 WADL Parser
 Well, maybe…
29
Future of ORM
 Much Work Needed
 What is natural way to handle object deletion?
 What is best way to handle complex keys?
 What is best way to bring in objects?
 What sort of cache policy should be used?
 Support Object-First Style
 With annotations?
30
Future of Annotations
 Too Hard to Declare
 Far too much work!
 Introspection Axes Wrong
 Current code uses very unnatural order
 Add to TclOO?
 Depends on issues being resolved
 Find Cool Things to Do, e.g…
 Augment ORM?
 Ways of creating server-side REST bindings
31

Adventures in TclOO

  • 1.
    Adventures in TclOOor, Here’sSome Tricks I’ve Been Up To Donal Fellows University of Manchester / Tcl Core Team
  • 2.
    Outline  A QuickTclOO Refresher  Support Class for REST  Wrapping TDBC with ORM  Extending TclOO with Annotations  Where to go in the Future 2
  • 3.
  • 4.
    TclOO Refresher  ObjectSystem  Incorporated in 8.6, Package for 8.5  Designed for  Keeping Out of Your Way  Being Tcl’ish and Dynamic  Being Powerful and Extensible  Key Features  Single-Rooted Inheritance Hierarchy  Classes are Objects and May be Extended  Object’s Namespace contains Object’s Variables  Class (Re-)Definition by Separate Command 4
  • 5.
    The Anatomy Lesson oo::object Namespace Method Table Mixin List Variables NSPath Commands Instance Method Table Mixin List Superclass List oo::class An object has these things… A class also has these, which apply to instances Classes are objects Objects are made by classes You can subclass the class of classes for custom construction 5
  • 6.
  • 7.
    REpresentational State Transfer REST is Way of Doing Web Services  Popular  Easy to Use in Ad Hoc Way  Strongly Leverages HTTP  Verbs are GET, PUT, DELETE, POST, …  Nouns are Resources with URLs  View of Resources Determined by Content Negotiation 7
  • 8.
    Example…  http://example.org/pizzas isa Pizza Parlor  GET http://example.org/pizzas  Returns Current List of Pizzas  GET http://example.org/pizzas/123  Returns Description of Pizza #123  GET http://example.org/pizzas/123/pepperoni  Returns Amount of Pepperoni on Pizza 8
  • 9.
    Example… Updates  PUThttp://example.org/pizzas/123/pepperoni  Sets Amount of Pepperoni on Pizza #123  Idempotent  POST http://example.org/pizzas  Makes a New Pizza from Scratch  Request document says what to make  Redirects to Created Pizza  DELETE http://example.org/pizzas/123  Gets Rid of Pizza #123  Idempotent 9
  • 10.
    REST Class  TclOOClass  Wrapper for http package  Models a Base Resource  Methods for Each HTTP Verb  Designed to be Subclassed!  Some Production Use  Testing Interface for Very Complex REST Service  More than 35 Operations with non-fixed URLs  Still Growing… 10
  • 11.
    General Plan oo::object Service InstanceService InstanceService Instance oo::class REST Specific Service 11
  • 12.
    Code (Simplified) methodDoRequest{ methodurl {type""} {value ""}} { for {setrs0} {$rs< 5} {incrrs} { settok [http::geturl $url -method $method -type $type -query $value] try { if{[http::ncode $tok] > 399} { # ERROR setmsg [myExtractError $tok] return -code error $msg } elseif {[http::ncode $tok] > 299 ||[http::ncode $tok]==201} { # REDIRECT try { setlocation [dictget [http::meta $tok] Location] } on error {} { error"missing location!" } myOnRedirect $tok $location } else{ # SUCCESS return[http::data $tok] } } finally { http::cleanup $tok } } error"too many redirections!" } methodGETargs { return [myDoRequest GET $base/[join $args"/"]] } 12
  • 13.
    Usage oo::class create Service{ superclass REST # … etc … methodstatus {{status""}} { if {$statuseq""} { return[my GET status] } my PUT status text/plain $status return } } 13
  • 14.
    Bioscience ServicesBioscience ServicesBioscience Services What I WasUsing This For Workflow Server Web FrontEnd Database Filesystem Heliophysics ServicesHeliophysics ServicesHeliophysics Services Chemistry ServicesChemistry ServicesChemistry Services Workflow Workflow Workflow Taverna 2 Server Taverna Engine Taverna Engine Taverna EngineTesting This Part 14
  • 15.
  • 16.
    Object-Relational Mapping  Objectsare Natural Way to Model World  Well, much of it…  Relational Databases are Excellent at Managing Data  Build Links between Objects and Databases  Many Languages Have Them  Java, C#, Ruby, …  Wanted to do in Tcl  Leverage TclOO and TDBC 16
  • 17.
    Data First orObjects First?  Data First  Data is already in the database  How to introspect database’s structure  How to represent naturally as objects  Objects First  Data is in objects  How to construct database to store and restore  My ORM Package is Data First  Dynamic class construction! 17
  • 18.
    Basic Class Plan oo::objectoo::class Database Table NamedRow AnonRow Instance makes instance subclass 18
  • 19.
    CRM DB Interaction Plan Database Table NamedRow Order DescnCustI D DispID Customer FirstName Surname Dispatch ID House Street City ID ID State crmdb orderorder#42 customer dispatch customer#7 dispatch#9 Introspects DB Columns go to properties Foreign keys make inter-object links Class per table Instance per row 19
  • 20.
    Example of Use #Connect to Database with TDBC setconn [tdbc::sqlite3::connection new"mydb.sqlite3"] # Create all the classes holding the mapping ORM::Databasecreatedb $conn # Illustrate use by printing out all orders db table order foreachordr { puts"Order #[$ordr id]" puts"Customer: [[$ordr customer] firstname] [[$ordr customer] surname]" puts"Address: [[$ordr dispatch] house] [[$ordr dispatch] street]" puts"Address: [[$ordr dispatch] city], [[$ordr dispatch] state]" puts"Description:nt[$ordr description]" puts"" } 20
  • 21.
  • 22.
    What is anAnnotation?  Additional Arbitrary Metadata  Attached to Class or Part of Class  User-Defined Purpose  Easy way to add information without doing big changes to TclOO’s C implementation  Uses from Other Languages  Documentation  Constraints  Coupling to Container Frameworks  Persistence, Web Apps, Management, … 22
  • 23.
    Annotation Syntax @SomeAnnotation -foobar oo::class createExample { @AnotherAnnotation variablex @GuessWhatThisIs constructor {} { … } @HowAboutThis? @More… methodxyzzy {xy} { … } } # To read the annotations… puts [infoclassannotation Example] 23
  • 24.
    Types of Annotations Annotations Specify What They Attach To  Classes  Methods  Any declaration…  Examples  @Description  @Argument  @Result  @SideEffect 24
  • 25.
    Declaring an Annotation oo::classcreateAnnotation.Argument { superclassAnnotation.Describe variableannotationmethod argument # Save what argument this applies to constructor{type argNameargs} { setargument $argName next $type {*}$args } # How an annotation is introspected methoddescribe{v {n""} {an""}} { upvar 1 $vresult if {[llength [infolevel 0]] == 3} { lappendresult $method return } if{$method ne $n} { return } if{[llength [infolevel 0]] == 4} { lappendresult $argument return } elseif {$argumenteq$a} { setresult [join $annotation] return -code break } } } 25
  • 26.
    Under the Hood Every Class has List of Annotations Applied to it  Attaching to Classes  Uses Standard Unknown Handler  Rewrites oo::class Command  Attaching to Declarations  Rewrites Whole TclOO Declaration System  Change Declaration  Local Unknown Handler  Adding Introspection  Extra commands in [info class] via ensemble 26
  • 27.
    Under the Hood TclOOPackage Annotation Package oo::class oo::define [info class] interceptor interceptors extensions Annotation Class Annotation Store Meddleswithinternals 27
  • 28.
  • 29.
    Future of RESTClass  Contribute to Tcllib  Needs More Features First  Authentication Support  Cookie Handling  WADL Parser  Well, maybe… 29
  • 30.
    Future of ORM Much Work Needed  What is natural way to handle object deletion?  What is best way to handle complex keys?  What is best way to bring in objects?  What sort of cache policy should be used?  Support Object-First Style  With annotations? 30
  • 31.
    Future of Annotations Too Hard to Declare  Far too much work!  Introspection Axes Wrong  Current code uses very unnatural order  Add to TclOO?  Depends on issues being resolved  Find Cool Things to Do, e.g…  Augment ORM?  Ways of creating server-side REST bindings 31