{"action":"created","issue":{"url":"https://api.github.com/repos/altmetric/embiggen/issues/1","labels_url":"https://api.github.com/repos/altmetric/embiggen/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/altmetric/embiggen/issues/1/comments","events_url":"https://api.github.com/repos/altmetric/embiggen/issues/1/events","html_url":"https://github.com/altmetric/embiggen/issues/1","id":68621032,"number":1,"title":"Use a sum type instead of exceptions","user":{"login":"mudge","id":287,"avatar_url":"https://avatars.githubusercontent.com/u/287?v=3","gravatar_id":"","url":"https://api.github.com/users/mudge","html_url":"https://github.com/mudge","followers_url":"https://api.github.com/users/mudge/followers","following_url":"https://api.github.com/users/mudge/following{/other_user}","gists_url":"https://api.github.com/users/mudge/gists{/gist_id}","starred_url":"https://api.github.com/users/mudge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mudge/subscriptions","organizations_url":"https://api.github.com/users/mudge/orgs","repos_url":"https://api.github.com/users/mudge/repos","events_url":"https://api.github.com/users/mudge/events{/privacy}","received_events_url":"https://api.github.com/users/mudge/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/altmetric/embiggen/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-04-15T09:06:21Z","updated_at":"2015-04-15T09:17:07Z","closed_at":null,"body":"The reason we have two separate expansion methods (`Embiggen::URI#expand` and `Embiggen::URI#expand!`) is to communicate the following things to the user:\r\n\r\n* The expanded URI;\r\n* If expanding a shortened URI failed because it did not redirect successfully;\r\n* If expanding a shortened URI failed because it redirected too many times.\r\n\r\nAt the same time, we want to provide a graceful API which tolerates failures for users that don't mind if URI expansion fails (and so doesn't unnecessarily raise exceptions).\r\n\r\nRather than having two separate methods (one graceful, one exception-happy), we could instead have a single `Embiggen::URI#expand` method which returns a [sum type](http://en.wikipedia.org/wiki/Tagged_union) to communicate some of the above without disrupting control flow:\r\n\r\n```ruby\r\nEmbiggen::URI('http://www.altmetric.com').expand\r\n#=> #<ExpandedURI http://www.altmetric.com>\r\n\r\nEmbiggen::URI('http://toomanyredirec.ts').expand\r\n#=> #<ShortenedURI http://toomanyredirec.ts>\r\n\r\nEmbiggen::URI('http://badshortenedu.rl').expand\r\n#=> #<BadShortenedURI http://badshortenedu.rl>\r\n```\r\n\r\nThese types could wrap a standard Ruby `URI` object so they can be used seamlessly with other libraries.\r\n\r\nThis would then be graceful (viz. failure to expand would not raise an exception or return `nil`) but users could check the return value if they wanted to ensure expansion was successful (we could provide a `Embiggen::URI#expanded?` helper rather than switching on type)."},"comment":{"url":"https://api.github.com/repos/altmetric/embiggen/issues/comments/93278327","html_url":"https://github.com/altmetric/embiggen/issues/1#issuecomment-93278327","issue_url":"https://api.github.com/repos/altmetric/embiggen/issues/1","id":93278327,"user":{"login":"scottmatthewman","id":18256,"avatar_url":"https://avatars.githubusercontent.com/u/18256?v=3","gravatar_id":"","url":"https://api.github.com/users/scottmatthewman","html_url":"https://github.com/scottmatthewman","followers_url":"https://api.github.com/users/scottmatthewman/followers","following_url":"https://api.github.com/users/scottmatthewman/following{/other_user}","gists_url":"https://api.github.com/users/scottmatthewman/gists{/gist_id}","starred_url":"https://api.github.com/users/scottmatthewman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scottmatthewman/subscriptions","organizations_url":"https://api.github.com/users/scottmatthewman/orgs","repos_url":"https://api.github.com/users/scottmatthewman/repos","events_url":"https://api.github.com/users/scottmatthewman/events{/privacy}","received_events_url":"https://api.github.com/users/scottmatthewman/received_events","type":"User","site_admin":false},"created_at":"2015-04-15T09:17:07Z","updated_at":"2015-04-15T09:17:07Z","body":":+1: Really like this idea. Feels like a much more elegant way of expressing resultant behaviour. Not to mention that relying on exceptions for control flow is slow (see [slides 47-8 of Erik Michaels-Ober's talk on **Writing Fast Ruby**][fast-ruby]), and when resolving URLs we tend to want to be as quick as possible.\r\n\r\n[fast-ruby]: https://speakerdeck.com/sferik/writing-fast-ruby"}}