Skip to content

Instantly share code, notes, and snippets.

@marcus
Forked from defunkt/url_dsl.rb
Created December 14, 2009 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcus/256352 to your computer and use it in GitHub Desktop.
Save marcus/256352 to your computer and use it in GitHub Desktop.
require 'open-uri'
# url dsl -- the ultimate url dsl!
#
# You just can't beat this:
#
# $ irb -r url_dsl
# >> include URLDSL
# => Object
# >> http://github.com/defunkt.json
# => #<URLDSL::Request http://github.com/defunkt.json/>
# >> puts http://github.com/defunkt.json
# [{"repository":{"url":"http://github.com/defunkt/repl",
# ... etc ...
# => nil
#
# Or this:
#
# >> require 'json'
# => true
# >> url = http://twitter.com/statuses/show/6592721580.json
# => #<URLDSL::Request http://twitter.com/statuses/show/6592721580.json/>
# >> JSON.parse(url.to_s)['text']
# => "He nose the truth."
#
# Helper for using URLDSL in a Ruby file:
#
# URLDSL do
# puts http://twitter.com/brosner/status/6592721580.json
# end
def URLDSL(&block)
$urldsl_req = URLDSL::Request.new
$urldsl_req.instance_eval(&block)
ensure
$urldsl_req = nil
end
module URLDSL
# This included hack is for `irb':
#
# >> include URLDSL
# => Object
# >> http://github.com/api/v2/yaml/repos/show/schacon/grit
# => <yaml>
def self.included(base)
$urldsl_req = URLDSL::Request.new
base.class_eval do
def method_missing(*args, &block)
$urldsl_req.send(*args, &block)
end
end
end
module SymbolHack
def /(other = nil)
return super unless other.is_a? Request
other << "/"
other
end
end
Symbol.send :include, SymbolHack
module NumberHack
def method_missing(name, *args)
$urldsl_req << self
$urldsl_req << name
self
end
end
Integer.send :include, NumberHack
class Request
attr_accessor :protocol, :calls
def initialize
@calls = []
@protocol = :http
end
def <<(method)
@calls << method
end
def url
build_url
ensure
@calls = []
end
def build_url
protocol.to_s + '://' +
@calls.join('.').
gsub('./', '/').
gsub('/.', '/').
squeeze('/')
end
def to_s
@to_s ||= open(url).read
end
def inspect
"#<URLDSL::Request %s>" % build_url
end
def method_missing(name, *args)
@to_s = nil
if name.to_s =~ /https?/
@protocol = name
else
self << name
end
args.each do |arg|
self << arg unless arg.is_a?(Request) || @calls.include?(arg)
end
self
end
end
end
URLDSL do
puts http://twitter.com/statuses/show/6592721580.json
require 'yaml'
url = http://github.com/api/v2/yaml/repos/show/schacon/grit
puts YAML.load(url.to_s)['repository'][:name]
end if $0 == __FILE__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment