-
Twilio.rb: The Ruby way to interact with the Twilio API←link!
Twilio.rb is a library I built for my company Shrewple
-
yo rubyists!
tell me which banks, investment banks, etc use ruby contractors.
contact me:
$ ruby -e 'puts [115, 106, 116, 103, 114, 97, 104, 97, 109, 64, 109, 97, 99, 46, 99, 111, 109].pack "c*"'
:)
-
method missing mischief
Ruby has many cool language features that make it quite straightforward to implement dynamic behaviour. One of those features is method_missing. It’s in the Kernel module, which means it is available everywhere. When a method is called on an object in Ruby and that method does not exist on the object, the object calls method_missing on itself and passes in the method name, arguments, and a block if one was yielded to the absent method. The default behaviour is to super up the inheritance chain, and if it reaches the top of the chain, i.e. method_missing has not been redefined in any of the superclasses, a NoMethodError exception is raised.
method_missing can be used to excellent effect, a famous example is the dynamic finder behaviour in ActiveRecord, e.g. Model.find_by_arbitrary_attribute.
When implementing something such as this, it’s responsible to super up the inheritance chain if the method called is not something you want to intercept. Consider the following:
def method_missing(meth, *args, &blk) #:nodoc meth = meth.to_s if meth =~ /\=$/ add_attr_writer meth send meth, args.first elsif meth =~ /^#{meth}\?/i add_predicate meth send meth elsif self[meth] add_attr_reader meth send meth else super end end endThe code is matching the method name against regular expressions and then executing the relevant code path. Aha! You may think, meth is passed in as a symbol, there is no #=~ method on Symbol, so let’s just convert the meth variable to a string and do it once! There is a big problem with this. If the execution path does call super, you will get an ArgumentError with the cryptic “id not given” and not a NoMethodError. This is because in the Ruby C source, method missing wants a symbol. This is one of the cases where Ruby does care of the the type of object!
static VALUE rb_method_missing(argc, argv, obj) int argc; VALUE *argv; VALUE obj; { ID id; VALUE exc = rb_eNoMethodError; const char *format = 0; NODE *cnode = ruby_current_node; if (argc == 0 || !SYMBOL_P(argv[0])) { rb_raise(rb_eArgError, "no id given"); } stack_check(); ... return Qnil; }The correct thing to do is leave the method id passed in untouched, and mess around with a copy, e.g.
def method_missing(id, *args, &blk) #:nodoc id = meth.to_s if meth =~ /\=$/ add_attr_writer meth send meth, args.first elsif meth =~ /^#{meth}\?/i add_predicate meth send meth elsif self[id] add_attr_reader meth send meth else super end end endThen a NoMethodError will be raised if the execution path is super.
The moral of the story? Ruby gives you a lot of rope, but does nothing to stop you hanging yourself with it!
-
I wrote a Twilio Ruby gem
Twilio is a wicked service that allows developers to build telephony into their applications without worrying about any of the telephony stuff. As long as your app speaks REST you’re good!
Unfortunately the official Ruby API wrapper library is janky as hell, e.g. how to make a call:
# Twilio REST API version API_VERSION = '2010-04-01' # Twilio AccountSid and AuthToken SID = 'ACXXXXX' TOKEN = 'YYYYYYYY' # Outgoing Caller ID previously CALLER_ID = 'NNNNNNNNNN'; a = Twilio::RestAccount.new(SID, TOKEN) d = { 'From' => CALLER_ID, 'To' => '415-555-1212', 'Url' => 'http://demo.twilio.com/welcome', } r = a.request( "/#{API_VERSION}/Accounts/#{SID}/Calls", 'POST', d)It’s not very pretty or concise. Also there is no abstraction and the constants are polluting the global namespace.
Not only that but it has no test coverage for the API integration! So I wrote something a little more Ruby like
# Do this configuration once in your app during initialization Twilio::Config.setup do account_sid 'ACXXXXXXXXX' auth_token 'YYYYYYYYYYYY' end # How to make a call Twilio::Call.create :to => '+1417555000', :from => '+1917555000', :url => 'http://example.com/'Omnomnom! Voice calls and SMS messages are currently fully implemented. The remainder of the API will be implemented shortly.
It also has complete test coverage. Win!
-
I just made a phone call from the command line
I used a new Twilio gem that I wrote for my latest project. It goes a little something like this:
Twilio::Call.create :to => '+19175551234', :from => '+19175550000', :url => 'http://example.com/api'If you’ve ever used Twilio in Ruby before, you’ll know how much straightforward that is compared to the official library. I’m pushing to Github soon.
Typing some shit into irb and have a phone ring is so 1337!
-
Give me Infinity
In Ruby, dividing a kind of Integer, e.g a Fixnum or Bignum by 0 will result in a ZeroDivisionError. Make the divisor and/or the dividend a float, e.g. 1.0/0, 1/0.0, 1.0/0, or 1.0/0.0 and an exception will not be raised, the quotient returned will be Infinity.
It can be quite useful, I used this today for some discount code, i.e. sometimes a discount should never be applied.
ruby-1.9.2-p0 > 1/0 ZeroDivisionError: divided by 0 from (irb):1:in `/' from (irb):1 from /Users/stevegraham/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `<main>' ruby-1.9.2-p0 > 1/0.0 => Infinity
For negative Infinity, make the dividend or the divisor negative.
-
Woot!
Just had my first patch committed to Ruby on Rails. It makes ActiveRecord::Base.find faster.
commit: http://bit.ly/9zrqS0
Thanks to José Valim for committing it!
-
Apple Engineer Laurent Sansonetti confirms Apple is porting MacRuby to iOS←link!
Hear the sound of Ruby developers around the world gearing up for not one but TWO lucrative, hungry markets competing for their skills: Web apps and iOS development.
Time to turn the money printing press up to 11 kids!
-
Array#map_with_index
Further on from my colleague Craig Webster’s post. I saw that a lot of people have wanted Array#map_with_index over the years. I found the existing implementations to be unnecessarily complex. Ruby allows something much simpler.
class Array def map_with_index &blk enum_with_index.map &blk end alias :collect_with_index :map_with_index end %w(one two three).map_with_index do |item, index| [item, index] endIf you happen to be one of the cool kids on 1.9 the solution if even more delicious and expressive.
%w(one two three).map.with_index do |item, index| [item, index] end
This is because when one calls and method from Enumerable without supplying a block, an instance of Enumerator is returned. Nice!
-
The Symbol#to_proc myth←link!
Symbol#to_proc performing like a dog is simply just not true anymore.
-
Stabby Lambdas & Curried Functions
Starting a new project at work in Ruby 1.9, I noticed there is a new syntax for creating lambdas:
a = ->(a,b) { a**b }This is equivalent to the conventional
b = lambda { |a,b| a**b }Thus:
a[2,5] == b[2,5]
My opinion is split on the aesthetic appeal of this new syntax, sure it’s brief but it’s also erlang-y. Fortunately it does have a useful feature, i.e. the ability to give default values to block parameter. This is not possible:
lambda { |a,b=2| a**b }This is:
->(a,b=2) { a**b }Currying, i.e. partial application of functions also appear
pow = ->(a,b) { a**b }.curry => #<Proc:0x00000100b021b8 (lambda)> square = pow[2] => #<Proc:0x00000100aff2b0 (lambda)> square[2] => 4 square[4] => 16 square[16] => 256Proc#call has also been aliased as Proc#=== meaning one can use lambdas in case statements… WUUUUUTTT!
S
-
Quick Tip: Ruby Class Definition
Everyone knows this syntax
class Foo end
This is cleaner when you just need to quickly define an empty class:
Foo = Class.new
I’m writing this ActiveRecord compliant in memory model implementation called Glamazon for this secret project I’m on at work. I used Class.new’s ability to take a block as the class body to include my library into a testable class, e.g.
Mule = Class.new { include Glamazon::Base }In other Ruby code you might frequently see this used to define error classes:
class SpecialError < StandardError end
This is way cleaner:
SpecialError = Class.new StandardError
s
-
A Tasty RSpec Morsel
RSpec’s let method is not hugely known but it’s very useful for DRYing up one’s specs. It accepts a symbol and a lazily evaluated block that defines a method when the method name is called
let(:foo) { puts 'METAPROGRAMMING FTW!' }Even less known is that due to way Ruby (< 1.9) works under the covers, one can pass in block variables and have the method magically accept arguments when it’s called.
I used this at work to stub out different API responses, and I came up with this little piece of sugar
let(:api_stub) { |code,response| FakeWeb.register_uri :get, %r|#{API_ENDPOINT}|, :status => [code, response] } # Usage: api_stub '401', 'Unauthorized'Yum!
-
Processing streaming JSON asynchronously is a piece of cake with YAJL and EventMachine
At work we are planning a redesign of our architecture into a services oriented style. It makes a lot of sense for us and will enable us to scale the areas of the application that need it while avoiding us wasting extra resources on areas of the application that are doing just fine as they are. It’s some seriously sexy shit, trust me. That and working with insanely smart cats has me jumping out of bed every morning.
One of the first things I needed to do was find away to consume a stream of data asynchronously. Since the data is a stream is delivered in arbitrary chunk sizes, not as discrete JSON objects I had a problem. Somehow I had to parse this.
Turns out it isn’t a problem. Thanks to YAJL and EventMachine
Check the Beautiful, simple, sweet, sweet code
P.S. If you run the code, observe the general asininity of Twitter’s user base… Fuck Twitter.
Love
S
-
Shoulda: with vs. without
ActiveRecord spec without shoulda:
describe Address do let(:address) { Factory.build :valid_address } %w(street_address locality region postal_code country).each do |attribute| it "is invalid without #{attribute}" do address.send "#{attribute}=", nil address.should_not be_valid address.errors.on(:"#{attribute}").should include "can't be blank" address.send "#{attribute}=", 'valid input' address.should be_valid end end endActiveRecord spec with Shoulda:
describe Address do it { should validate_presence_of :street_address } it { should validate_presence_of :locality } it { should validate_presence_of :region } it { should validate_presence_of :postal_code } it { should validate_presence_of :country_name } endEven using a healthy dash of metaprogramming to make the first example as brief as possible, it’s clear shoulda wins hands down for brevity, readability, and concision.
s
Tue28Dec
Sat09Oct
Thu30Sep
Tue28Sep
Mon27Sep
Wed22Sep
Mon20Sep
Sun12Sep
Sat11Sep
Sun15Aug
Sat07Aug
Sat24Jul
Thu22Jul
Sat17Jul
Sun11Jul