Cleanliness is Next to Domain-Specificity

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    1 Favorite & 1 Group

    Cleanliness is Next to Domain-Specificity - Presentation Transcript

    1. Cleanliness is Next to Domain-Specificity Ben Scofield Senior Developer Viget Labs 4 November 2007 © Copyright 2007 Viget Labs, LLC – www.viget.com
    2. Part 1: Linguistics Part 2: Refactoring
    3. The Ruby Community
    4. http://www.flickr.com/photos/jesper/1395418767/ Interdisciplinary
    5. Linguistics
    6. Categories
    7. Regional Dialects
    8. (more) Regional Dialects
    9. Jargons Cants
    10. Pidgins and Creoles
    11. Vocabulary Grammar
    12. Real DSLs Ruby Domain-Specific Code
    13. ActiveRecord
    14. RSpec
    15. Same Grammar, Different Vocabulary
    16. Who Cares?
    17. DSLs DSL Intimidate and Frighten http://www.flickr.com/photos/cwsteeds/58514985/
    18. Write a Parser? No, Thanks. http://www.flickr.com/photos/rooreynolds/243810988/
    19. http://www.flickr.com/photos/jonosd/498162310/
    20. Change the Vocabulary Change the World Heroes on NBC - Mondays at 9 PM
    21. API vs. Dialect
    22. Why DSanything?
    23. Who Are We?
    24. http://www.oreillynet.com/onlamp/blog/2006/05/ sapirwhorf_is_not_a_klingon.html http://tech.puredanger.com/2006/11/08/does-your-programming- language-affect-how-you-think/ http://snakesgemscoffee.blogspot.com/2006_11_01_archive.html http://talklikeaduck.denhaven2.com/articles/2007/06/11/sapir- whorf http://adams.id.au/blog/2007/10/what-is-behaviour-driven- development/ http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/75914 http://www.weiqigao.com/blog/2007/09/10/ an_interesting_experiment_sapir_whorf_hypothesis.html http://www.ibm.com/developerworks/blogs/page/pmuellr? tag=ruby http://intertwingly.net/blog/2007/10/05/NOC http://brooders.net/category/perl/ http://gilesbowkett.blogspot.com/2007/02/sapir-worf-in- action_19.html http://blogs.msdn.com/daveremy/archive/2005/04/06/ sapirwhorfs.aspx http://erlangish.blogspot.com/2007/05/shape-of-your-mind.html http://www.oreillynet.com/onlamp/blog/2006/06/ how_does_a_programming_languag.html
    25. Linguistic Determinism
    26. The Hopi
    27. Linguistic Relativism
    28. http://www.flickr.com/photos/maxhunter/79993854/ Snow qanuk avalanche kaneq blizzard kanevvluk dusting natquik flurry nevluk frost aniu hail qanikcaq hardpack muruaneq igloo nutaryuk pingo qanisqineq powder qengaruk sleet utvak slush navcaq snow pirta snowflake pirtuk snowstorm ... ...
    29. Color Perception http://www.flickr.com/photos/thedeplorableword/140856437/
    30. Direction of Causality Degree of Influence
    31. RSpec  Sapir-Whorf
    32. Testing is Too Late
    33. Specifications Come First
    34. RSpec Leads You in the Right Direction
    35. DSDs are Built on Linguistic Relativism
    36. Keep Your Head in the Domain
    37. Refactoring
    38. Tastes Vary
    39. ?
    40. Finding a Ticket
    41. kayak.com
    42. What Does This Do?
    43. Ruby? Awesome!
    44. exit 0 @@results.each do |r| if searchtype == 'h' puts \"#{r.price} url=#{r.url}\" puts \"#{r.stars} #{r.name} $#{r.loprice} - $#{r.hiprice}\" elsif searchtype == 'f' puts \"#{r.price} url=#{r.url}\" r.legs.each do |leg| puts \" #{leg}\" end end end exit(0) more = poll_results_file(searchtype) @@results.each do |r| puts \"#{r.price} #{r.url}\" r.legs.each do |leg| puts \" #{leg}\" end end end Whoa.
    45. Start at the End
    46. I Want to: find flights from CLT to RDU leaving today and returning in one week
    47. I Want to: find :flights, :from => :CLT, :to => :RDU, :leaving => Date.today, :returning => Date.today + 7
    48. 48 40 The Old Way sid = getsession(@@token) searchid = start_flight_search(sid, ‘n’, ‘CLT’, ‘RDU’, Date.today, nil, 1) more = poll_results('f', sid, searchid, nil) while more == 'true' do more = poll_results('f', sid, searchid, nil) sleep(3) end def poll_results(searchtype, sid, searchid, count) url = \"/s#{@@sparkleinstance}/apibasic/flight?searchid=#{searchid}&apimode=1&_sid_=#{sid}\" more = nil Net::HTTP.start(@@hostname, @@port) do |http| if count url += \"&c=#{count}\" end response = http.get(url) body = response.body File.open(\"ksearchbody.xml\", \"w\") do |f| f.puts(body) end more = handle_results(searchtype, body) if more != 'true' # save the body, so we can test without doin # an actual search File.open(\"ksearchresults.xml\", \"w\") do |f| f.puts(body) end end end return more end
    49. 48 40 The Old Way, cont. def handle_results(searchtype, body) xml = REXML::Document.new(body) more = xml.elements['/searchresult/morepending'] @@lastcount = xml.elements['/searchresult/count'].text @@sparkleinstance = xml.elements['/searchresult/searchinstance'].text if more more = more.text end if more != 'true' @@results = [] #puts \"count=#{@@lastcount}\" xml.elements.each(\"/searchresult/trips/trip\") do |e| trip = Trip.new() e.each_element(\"price\") do |t| trip.price = t.text trip.url = t.attribute(\"url\") end e.each_element(\"legs\") do |legs| legs.each_element(\"leg\") do |l| leg = Leg.new l.each_element do |ld| # extract the detail from each leg case when ld.name == 'airline': leg.airlinecode = ld.text #... end end trip.legs << leg end # leg in legs loop end # legs in trip loop #e.each_element(\"/searchresult/trips/trip/price\") { |p| trip.price = p.text } #puts \"trip: #{trip.price}\" @@results << trip end # each trip end return more end
    50. 40 Output session_url = \"/k/ident/apisession?token=#{token}\" search_url = \"/s/apisearch?basicmode=true&oneway=n&origin=#{origin} &destination=#{destination}&destcode=&depart_date=#{dep_date} &depart_time=a&return_date=#{ret_date}&return_time=a&travelers=# {travelers}&cabin=e&action=doflights&apimode=1&_sid_=#{sid}\" results_url = \"/s#{@@sparkleinstance}/apibasic/flight?searchid=# {searchid}&apimode=1&_sid_=#{sid}\"
    51. 40 Expectations class KayakTest < Test::Unit::TestCase def test_find_should_call_out_to_session_endpoint setup_mocks_for_find Kayak.find :flights end private def setup_mocks_for_find response = mock(:body => '<?xml version=\"1.0\"?> <ident> <uid>uid</uid> <sid>0123456789</sid> <token>12345</token> <error></error> </ident>') success = mock() success.expects(:get).with('/k/ident/apisession?token=12345').returns (response) Net::HTTP.expects(:start).at_least_once.yields(success) end end
    52. 40 Parsing Responses class KayakTest < Test::Unit::TestCase def test_session_response_should_be_parsed_for_session_id setup_mocks_for_find Kayak.find :flights assert_equal '0123456789', Kayak.session_id end private def setup_mocks_for_find response = mock(:body => '<?xml version=\"1.0\"?> <ident> <uid>uid</uid> <sid>0123456789</sid> <token>12345</token> <error></error> </ident>') success = mock() success.expects(:get).with('/k/ident/apisession?token=12345').returns (response) Net::HTTP.expects(:start).at_least_once.yields(success) end end
    53. class Kayak First Cut @@session_id = nil @@search_id = nil @@search_options = {} TOKEN = '12345' HOSTNAME = 'www.kayak.com' PORT = 80 class << self def session_id @@session_id end def method_missing(name, *args) @@search_options[name] end def find(type, conditions = {}) session_id ||= initialize_session @@search_options[:origin] = conditions[:from] @@search_options[:destination] = conditions[:to] @@search_options[:depart_date] = conditions[:leaving].strftime('%m/%d/%Y') if conditions[:leaving] @@search_options[:leave_date] = conditions[:returning].strftime('%m/%d/%Y') if conditions[:returning] search_id ||= initialize_search self end def initialize_search Net::HTTP.start(HOSTNAME, PORT) do |http| response = http.get(\"/s/apisearch?basicmode=true&oneway=n&destcode=&depart_time=a&... if body = response.body xml = REXML::Document.new(body) @@search_id = xml.elements['//searchid'].text end end end def initialize_session Net::HTTP.start(HOSTNAME, PORT) do |http| response = http.get(\"/k/ident/apisession?token=#{TOKEN}\") if body = response.body xml = REXML::Document.new(body) @@session_id = xml.elements['//sid'].text end end end end end
    54. module Kayak Second Cut TOKEN = '12345' HOSTNAME = 'www.kayak.com' PORT = 80 class Flight attr_accessor :session, :search_id, :search_options def method_missing(name, *args) search_options[name] end def initialize(conditions = {}) session ||= Kayak::Session.new self.search_options = {} self.search_options[:origin] = conditions[:from] self.search_options[:destination] = conditions[:to] self.search_options[:depart_date] = conditions[:leaving].strftime('%m/%d/%Y') if conditions[:leaving] self.search_options[:return_date] = conditions[:returning].strftime('%m/%d/%Y') if conditions[:returning] Net::HTTP.start(HOSTNAME, PORT) do |http| response = http.get(\"/s/apisearch?basicmode=true&oneway=n&destcode=&depart_time=a&return_date=... self.search_id = Kayak.retrieve(response, '//searchid') end end def self.find(args) self.new(args) end end class Session attr_accessor :session_id def initialize Net::HTTP.start(Kayak::HOSTNAME, Kayak::PORT) do |http| response = http.get(\"/k/ident/apisession?token=#{Kayak::TOKEN}\") self.session_id ||= Kayak.retrieve(response, '//sid') end end end def self.find(type, *args) case type when :flights Kayak::Flight.find(*args) end end ...
    55. I Want to: find :flights, :from => :CLT, :to => :RDU, :leaving => Date.today, :returning => Date.today + 7
    56. Third Cut ?
    57. Always Room for Improvement
    58. Tips
    59. :symbol ignore the colon
    60. I Want to: find :flights, :from => :CLT, :to => :RDU, :leaving => Date.today, :returning => Date.today + 7
    61. Optional Parentheses looks like a sentence
    62. I Want to: find :flights, :from => :CLT, :to => :RDU, :leaving => Date.today, :returning => Date.today + 7
    63. Blocks for All In other languages, you have to specify explicitly that a function can accept another function as an argument. But in Ruby, any method can be called with a block as an implicit argument. Matz, 2003
    64. * arrays from anything
    65. Optional Braces not that common
    66. I Want to: find :flights, :from => :CLT, :to => :RDU, :leaving => Date.today, :returning => Date.today + 7
    67. • Start Modestly • Stay in the Domain • Get Better
    68. 56 That’s It travel safely
    69. Ben Scofield ben.scofield@viget.com http://www.extendviget.com/ http://www.culann.com/ 4 November 2007 © Copyright 2007 Viget Labs, LLC – www.viget.com

    + Ben ScofieldBen Scofield, 2 years ago

    custom

    1057 views, 1 favs, 0 embeds more stats

    Presentation from Rubyconf 2007 - on linguistics an more

    More Info

    © All Rights Reserved

    Go to text version
    • Total Views 1057
      • 1057 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 1
    • Downloads 30
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as innappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel

    Categories

    Groups / Events