Title: Learning to Live with the Static Typing Fascist and the Dynamic Typing Fanboy in your Enterprise...
1Learning to Live with the Static Typing Fascist
and the Dynamic Typing Fanboy in your
Enterprise...
- James Crisp and Jim Webber, ThoughtWorks
2Roadmap
- Platform
- Code affordances
- Tool support
- Extensibility
- Development Process
- Data access
- Metaprogramming
- Application development
- Integration
3Platform
- Windows!
- .Net 3.5
- Maybe Linux, via Mono
4Platform
- Anywhere
- Windows
- Linux
- Mac
- CLR
- JVM
5Readability
- How concise and readable is thecode?
- How much code will I have to maintain?
- How productive can I be?
6Attributes
- class Person
- attr id
- attr_accessor name, age
- end
7Named Parameters
- p Person.new(
- first_name gt "Freddy",
- last_name gt "Flintoff")
- p.update(age gt 72, sexgt'm')
8Default PropertyImplementation
- class Person
-
- public string FirstName
-
- get set
-
- ...
9Initialisers
- Person p new Person
- LastName "Dundee",
- FirstName "Mick"
10Meta Plumbing
- class DomainObject
- def initialize(attributes )
- attributes.each do name, value
- eval("_at_name value")
- end
- end
- end
11Duck Typing
- h House.new( number gt 20 )
- p Phone.new( number gt 123456 )
- p h
- p.number
- gtgt 20
12Type Inference
- var p new Person
- LastName "Smith"
13Who needs Duck Typing?
- interface INumbered
-
- int Number get
-
- class House INumbered ...
- class Phone INumbered ...
- INumbered phone
- INumbered house new House()
- phone house
- phone.Number
-
14Data
- LINQ and Entity Framework
- Castle project
- Active record for .Net
- Builds on NHibernate
- NHibernate too!
15Design Time
16Generate and Use theDatabase
- PersonDataContext pdc new
PersonDataContext() - pdc.CreateDatabase()
- var adults from p in pdc.Persons
where p.Age gt 18 select p - foreach (Person adult in adults)
-
- Console.WriteLine(adult.FirstName " "
- adult.LastName)
17Data
- Active Record ships with Rails
- Good for green field web apps
- Objects and properties mapped 11 to tables and
columns - Simple API for searching and saving
- Can use underlying platform eg, Hibernate or
NHibernate
18Lambda Functions
- What are Lambda functions?
- From the functional programming community
- Who?
- Think anonymous inline methods
- C 2.0 anonymous delegates with nicer syntax
19Pass a function into acollection
- ListltPersongt people new
ListltPersongt() - people.Add(new Person FirstName "James",
LastName "Crisp", Age 8 ) - people.Add(new Person FirstName "Jim",
- LastName "Webber", Age 32 )
- people.ForEach(p gt Console.WriteLine(p.FirstNa
me " " p.LastName))
20Lambda Functions
- codgers people.find p p.age gt 30
- codgers.each c print c.name
21Metaprogramming DSLs
- Method Missing
- DSLs
- Code generation at run time
22Method Missing
- If a method is not defined, falls through to
method_missing. - ActiveRecord (part of Rails) uses this to
generate properties on domain objects at run
time. - Allows DSLs like
- Person.find_by_name_and_age('Jim', 84)
23Code Generation atRun Time
- Create new properties, methods and classes on the
fly - Redefine, wrap and rename methods
- Eval() a string, and it will be code
24Code Generating DSL
- class Geek lt ActiveRecordBase
- has_many laptops
- has_one girlfriend
- end
- jim Geek.new(name gt 'Jim' )
- laptop Laptop.new(brandgt 'dell')
- jim.laptops ltlt laptop
25rSpec DSL
- describe Geek do
- before(each) do
- _at_geek Geek.new
- end
- it "should have no laptops initially" do
- _at_geek.laptops.count.should 0
- end
- ....
26Autogen andMetaprogramming
- Can generate useful code from metadata at compile
time - E.g. Domain objects from database schemas
- E.g. Service proxies from WSDL
- Etc
- Attributes for metaprogramming
- And the reflection APIs if I have to...
27DSLs
- Some support for fluent interfacesin NUnit etc
- Assert.That(...)
- Assert.IsNotNull(...)
- Can create our own DSLs by using cunning class
name conventions - E.g. nBehave for BDD
- Like TDD but focussed on behaviour rather than
implementation
28nBehave DSL
- override public void Specify()
-
- Given(new RubyProgrammer()).
- When(new BuildingProperSoftware()).
- Then(new RubyProgrammerShouldBeFired())
Tooling available to turn this code into
development stories for xBehave
29Extensible Type System
- All classes are open and can beextended
- Eg, Rails extends Ruby's number class
- gtgt 5.days.from_now
- gt Sun Aug 05 142812 1000 2007
- Existing methods can be removed, wrapped or
renamed - Frameworks often designed around re-usable Mixins
rather than inheritance
30Adding new methods
- class String
- def url?
- self.starts_with? "http//"
- end
- end
- gtgt "hi".url?
- gt false
- gtgt "http//jamescrisp.org".url?
- gt true
31Extensible Type System
- Weve always had interfaces andabstract classes
from the underlying .Net framework - Now we have extension methods too...
32Defining Extension Methods
- namespace JimWebber
-
- public static class WebUriValidator
-
- public static bool IsValidUri(this
string str) -
- return str.ToLower().StartsWith("http"
) -
-
33Using Extension Methods
- using JimWebber
- class Program
-
- static void Main(string args)
-
- string s "http//jim.webber.name"
- bool b s.IsValidUri()
-
34Testing
- Unit Testing
- TDD NUnit
- BDD nBehave
- nMock Interfaces easy, classes slightly trickier
35NUnit
- TestFixture
- public class PersonTest
-
- SetUp
- public void GivenAPersonExists()
- ..
- TearDown
- public void PersonShouldBeRemoved()
- ..
-
- Test
- public void PersonShouldBeOlderThanZero()
-
- ...
- Assert.That(p.Age gt 0)
-
36nMock Example
- InterfaceToBeMocked aMock
mocks.NewMockltIPersongt() - Stub.On(aMock).GetProperty("Age")
.Will(Return.Value(32)) - Expect.Once.On(aMock)
- .GetProperty("FirstName")
- .Will(Return.Value("Jim"))
37Testing
- TDD
- Unit test framework part of standardlibraries
- BDD
- rSpec, rBehave
- Mocks
- Mocha, rMock, FlexMock, etc
38Unit Test Example
- def test_person_is_called_james do
- assert_equal 'James', _at_person.nameend
- OR after a little bit of meta programming
- test 'person is called James' do assert_equal
'James', _at_person.nameend
39Mocha Example
- p mock('person')
- p.stubs(age).returns(26)
- p.expects(name).returns('James')
40Tool Support
- Visual Studio
- Intellisense, debugger, PowerShell, etc
- Continuous Integration
- CruiseControl.Net and friends
- Build Process
- NAnt, MSBuild, NMaven, etc
41PowerShell
- PS C\Users\Jim Webbergt name "Jim Webber"
- PS C\Users\Jim Webbergt name
- Jim Webber
- PS C\Users\Jim Webbergt name.ToLower()
- jim webber
- PS C\Users\Jim Webbergt
- PS C\Users\Jim Webbergt (xml(new-object
System.Net.WebClient).DownloadString("http//jim.w
ebber.name/feeds/atom.aspx") - ).feed.title
- World Wide Webber
42Tool Support
- IDE
- Visual Studio with Iron Ruby
- IntelliJ, e-Edit, TextMate provide syntax
highlighting and script support. - Build Process Rake
- Continuous Integration
- CruiseControl.rb and friends
43Console
- C\rubygtruby script/console
- gtgt p Person.new( name gt 'Jim' )
- gt ltPerson0x49c8d40
- _at_attributes"name"gt"Jim", ...gt
- gtgt p.save
- gtgt name 'Jim'
- gtgt Person.find(first, 'name ', name)
- gt ltPerson0x69c1d40
- _at_attributes"name"gt"Jim", ...gt
44Gems
- C\rubygt gem install mocha
- Bulk updating Gem source index for
http//gems.rubyforge.org - Successfully installed mocha-0.5.3
- Installing ri documentation for mocha-0.5.3...
- Installing RDoc documentation for mocha-0.5.3...
45NMaven
Warning NMaven currently immature
- Apache Incubator project
- Supports repositories for dependencies
- Across the Internet
- Plugs into the standard Maven build cycle
- Will have VS integration
- Extensible through Mono-based plugins
- Also could use Ivy for dependency management...
46Web Apps ? RAILS
- Rails is the most famous and popularRuby
framework - Rails provides (among other things)
- Neat MVC framework and route mapping
- Template based views
- Domain focussed business layer
- Active Record and DSLs for persistence
- Easy AJAX and Web 2.0 support
- Auto-generated code (write time and run time)
- Fast change cycle (edit file -gt refresh page)
- Plug-ins for code re-use
47Web Apps
- ASP.Net
- Plus new ASP.Net AJAX functionality
- Combine ASP.Net with Entity Framework for
Rails-like functionality - Silverlight
- For richer client functionality
48Rich Client
- Most Ruby dev is Rails and Web 2.0
- There are GTK / Gnome bindings for Ruby and some
rich client Ruby apps. - WPF under .NET
49Rich Client
- WPF
- Clear separation of markup andbusiness logic
- Whizzy acceleration and goodness from DirectX 10
- Also the older WinForms stuff is available
50Integration
- WCF
- WS-
- SOAP, WSDL, WS-Sec, WS-SecPol, WS-Trust,
WS-Federation, WS-Coordination.
WS-AtomicTransaction, WS-KitchenSink... - REST Support
- URI templates, WebGet, etc
- Enterprise-y stuff too
- Queues
51Integration
- REST-centric
- Web services are produced like web pages, using
same framework and routing - Message Queues using Reliable-Msg or underlying
JMS or MSMQ - WS- support
- SOAP4R
- Use underlying platform for WS-, eg, WCF or Java
frameworks like XFire
52XML and Friends
- .Net has XmlSerializer (and friends)
- Dom, XPath, templates, etc
- VB has XML literal support...
- Dim x As XElement ltdategt
ltyeargt2006lt/yeargt ltmonthgt01lt/monthgt
ltdaygt01lt/daygt lt/dategt
53C Not Tightly Coupled toXML
- var x new XElement("Date")
- x.Add(new XElement("Year", "2006"))
- x.Add(new XElement("Month", "01"))
- x.Add(new XElement("Day", "01"))
54XML and Friends
- XPath and Document Object Modelwell supported
- To generate complex XML (eg, LIXI), the best way
is templating using Erb - All objects have to_xml method with serialises
properties to xml - XML Builder is nice to work with and leverages
Ruby's flexible method_missing
55XML Builder
- gtgt builder.date
- ?gt builder.year "2006"
- gtgt builder.month "01"
- gtgt builder.day "01"
- gtgt
-
- ltdategt
- ltyeargt2006lt/yeargt
- ltmonthgt01lt/monthgt
- ltdaygt01lt/daygt
- ltdategt
56Coexisting in theenterprise
- When to go Ruby versuswhen to use C and .Net?
- Enterprise heavy lifting?
- Cross-language enterprise development?
- And what about mixing C and IronRuby...?
57Questions?
58Evaluation Forms