Mel Kaulfuss
Posted on September 10, 2020
The funniest thing happened to me yesterday. Funny now I guess. At the time it was distinctly unfunny. I struggled for hours on the simplest unit spec that was failing.
The response I was expecting to see in my test:
{:response=>{
"pspReference"=>"883598242852329J",
"resultCode"=>"Authorised",
"amount"=>{"currency"=>"AUD", "value"=>1000}
},
:header=>{ "Sandwich"=>"Eggplant-Parma-Sanga"},
:status=>200}
The failure message, less than helpful:
TypeError:
no implicit conversion of Symbol into Integer
Staring at the code.
Staring at the spec.
Thinking I'd done something stupid in my before
block.
A binding.pry
in my code shows me the Hash I'm expecting to be able to access with a :response
key is coming back inside an Array?!
[{:response=>{"pspReference"=>"883598242852329J", "resultCode"=>"Authorised", "amount"=>{"currency"=>"AUD", "value"=>1000}},
:header=>{"Sandwich"=>"Eggplant-Parma-Sanga"},
:status=>200}, “api_version”]
You wot m8!
It took a second pair of eyes to help spot the error.
def initialize(result:, api_version:)
@result = result, # <-------- this stray comma
@api_version = api_version
end
As soon as that silly stray comma was pointed out I laughed out loud.
I was accidentally Destructuring in Ruby and I'm chalking up the fact I knew that's what was happening as my win here! And also that I'd been meaning to write about Destructuring in Ruby earlier, so, win win I guess 🤷♀️
Destructuring is described in Common Lisp the Language, 2nd Edition as the ability to "bind a set of variables to a corresponding set of values anywhere that you can normally bind a value to a single variable".
In Ruby we assign values to a single variable like this
my_choice_sandwich = "eggplant parma"
# irb(main):001:0> my_choice_sandwich
# => "eggplant parma"
Destructuring allows us to do multiple assignments with a simple comma separating the multiple values like so
my_choice_sandwich = "crumbed eggplant", "sugo sauce", "mozzerella"
# irb(main):001:0> my_choice_sandwich
# => ["crumbed eggplant", "sugo sauce", "mozzerella"]
Above we see the Object on the left (the "variable") is an Array because we are passing in multiple values on the right.
You can set multiple variables (on the right) with corresponding values (on the left).
sandwich, pizzas = "salad", {vege: "mushrooms", meat: "aussie"}
# irb(main):001:0> sandwich
# => "salad"
# irb(main):001:0> pizzas
# => {:vege=>"mushrooms", :meat=>"aussie"}
Above you'll see:
sandwich
returns a String because only one value is being assigned on the right.
pizzas
returns a Hash as that was the corresponding value on the right.
Isn't learning fun!
Posted on September 10, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.