lolgramming

Because coding is fun(ny)

Testing on Mobile with Rails

When developing for mobile, you can get most of the way there by changing your viewport width to simulate a mobile device. But sometimes, that’s just not good enough.

Luckily, if you’re working on a Rails app, there’s an easy way to configure your local development environment so you can access it on any mobile device you need to test with.

Note: Before you try this out, make sure you’re on a secure private internet connection. Since your app will be listening on every network interface, you may be vulnerable if you’re on public or untrusted networks.

1. Find Your Internal IP

First, find out what your computer’s internal IP is behind your router. You can find this with ifconfig in the command line, or if you’re on a Mac, you can find it in System Preferences –> Network under the Status field for your wifi connection.


2. Launch Rails & Listen

Next, launch your rails app without binding to your development machine with rails s -binding=0.0.0.0. You can also use rails s -b 0.0.0.0 if the first command gives you trouble.

The -b flag binds the server to a specific IP, but by listening on 0.0.0.0 you allow any incoming connections to hit the app instead of only granting access to your local machine.

1
2
3
4
5
6
7
8
9
10
rails s -b 0.0.0.0

# => Booting Thin
# => Rails 4.1.4 application starting in development on http://0.0.0.0:3000
# => Run `rails server -h` for more startup options
# => Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
# => Ctrl-C to shutdown server
# Thin web server (v1.6.3 codename Protein Powder)
# Maximum connections set to 1024
# Listening on 0.0.0.0:3000, CTRL+C to stop

3. Go To There

Finally, get your device and enter your development computer’s internal IP and the app port in whatever browser you’re testing. Now you can hit your local app as you develop!


I’m Hired, Now What? The New Developer’s Survival Guide

So you’ve made it past the whiteboard interview, met most of the team, and accepted an offer for your first engineering job. Congratulations! It may feel like your ordeal is over, but in fact, your journey has just begun.

Whether you’re self-taught, coming from a four-year degree or fresh out of an immersive development program, you’ll quickly learn that day-to-day professional software development is a completely different animal from learning in a controlled environment.

Here are some of the things I’ve learned through my first engineering job that should help make for a smoother transition from student to pro developer.

Getting Set Up


Learning the Codebase

One of the biggest challenges you’ll have is getting acclimated to a legacy codebase. If this is your first time encountering a real production codebase, resist the urge to feel overwhelmed – you won’t need to know how everything works at first (possibly ever), and no one will expect you to as a new hire.

Instead, focus on understanding the common patterns and conventions being used to get a sense of how things operate. If there are multiple applications involved, concentrate on getting a good bead on how one of them works as opposed to jumping back and forth too much.

Close Reading Code

My former classmate Kyle Doherty recommends close reading code in his own blog post on this subject. Close reading – reading along with the code, while commenting every line to explicitly spell out to yourself what’s going on – is an excellent way to gain a meaningful understanding of what’s going on behind the scenes.

Investigate the Database

Looking at the database structure will also help speed your comprehension along. Even better, once you’ve got a decent grasp on its high-level workings, ask your coworkers about any ‘gotchas’ that tend to trip people up when interacting with the database.

If you want to be a real hero, document these things (if they haven’t been already) and make them available to the team – you’ll be bringing yourself up to speed, plus making it easier for future newbies to get up and running.

Everyday Practices


Once you’ve grown comfortable with the learning process – it’ll take quite a while to feel like you have a handle on everything – there are some everyday activities you can work into your routine to help smooth the process along.

Keep a Running Log

One thing that I found extremely helpful was taking detailed notes. Whatever I was working on – tracing an obscure error message, diagramming out a better pattern, debugging my environment – having a running text log I could refer back to whenever a similar issue came up quickly proved to be invaluable. Referencing the specific ticket number for the issue in the log can also help with locating relevant information fast.

Use Your Notes When Logging Tickets

Even better, once you’ve resolved an issue, this log instantly becomes the history of how you found the solution. Including this play-by-play into Jira or whatever issue-tracking software your team uses helps add to the team’s institutional knowledge for the next time something similar pops up.

Also, when working in the code on tickets, adding a comment with the corresponding ticket number when appropriate can help point future developers to relevant existing issues, and can make things easier for anyone who might pick up the task in the future.

Plan to Ask For Help

Knowing when to ask for help is critical, especially as a junior. A good rule of thumb would be to give yourself 45 minutes to find a solution. If you aren’t able to make meaningful progress by that point, definitely ask for help.

At that point you’ll be able to walk your coworker through everything you tried, and you’ll be extra-receptive to the solution for next time.

Regular Milestone Check-Ins


When you’re in the weeds, it can be hard to get the impression that you’re improving. Two regular practices can help yourself realize how much you really are learning on the job: Daily postmortems and weekly summaries.

Daily Postmortems

At the end of every day, simply write down 3-5 new things that you learned that day. Having trouble figuring out what they are? Guess what – if you’ve been keeping a running log, just read back through that!

Weekly Summaries

At the end of every week, write a simple summary of how it went, what you learned, and what’s on the horizon. I prefer a few bulleted sentences, but whatever works for you is great. If you’re having trouble thinking of things, just refer to that week’s daily postmortems!

Just Keep Learning

More than anything else, becoming a professional developer (like most things) is all about incremental improvements. The more mechanisms you create for yourself to retain and acknowledge your steady improvement, the faster you’ll learn – and the more fun you’ll have doing it.


Encoding Messages in Fake Spam Using Polymorphic Interfaces

There’s something interesting about spam. I’m not talking about the barrage of poorly-disguised junk mail everbody gets – I’m talking about the special kind of spam that combines just the right amount of unlikely phrase pairings and absurdist imagery to create a new kind of confusion unique to the modern age.

A few weeks ago, I made a steganography project, SpamEncoder, using this caliber of ‘spam as art’ as the medium to hide secret messages in.

It’s really simple to use – you just put the message you want to hide in the ‘Encode’ field, then press the button to instantly produce a coded version of the message. When you want to decode it, just copy the text in the ‘Decode’ field and press that button. Couldn’t be simpler!

However, getting this to work just how I wanted was a little trickier. Here’s how I did it.

Step 1: Case Statement

For the very first version of the app, I wanted to get something working as quickly as possible. Once I had a prototype up, it’d be much easier to see where the issues and unexpected problems would come from.

The first incarnation was a straight letter substitution, using a hideous case statement to swap out each letter of the original message for a new encoded word.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  # Encode method

  def encode_letter_replace(letter)
    case letter
    when "a"
      "cialis "
    when "b"
      "loans "
    when "c"
      "enhancement "
    when "d"
      "pills "
    when "e"
      "sale "
    when "f"
      "nigeria "
    ...

  # Decode method

  def message_reverse_engineer(message)
    message.gsub!("cialis ","a")
    message.gsub!("loans ","b")
    message.gsub!("enhancement ","c")
    message.gsub!("pills ","d")
    message.gsub!("sale ","e")
    message.gsub!("nigeria ","f")
    ...

Despite being as clunky as possible, it worked well enough to prove out the concept and bring a few issues to light I hadn’t anticipated:

1. The algorithm would need to handle lowercase and uppercase letters, as well as some special characters;

2. Challenges in swapping out individual characters with spam phrases instead of single spammy words; and

3. Preserving carriage returns in the original message.

Handling lowercase and uppercase letters was easy – I just added different phrase substitutions for all 52 case variations of the English alphabet, plus a few of the more common special characters. The others, however, were much more interesting.

2. Polymorphic Phrase Library

Replacing single characters with encoded phrases took a fair chunk of time to nail down. While the first version duplicated the entire character/spam word key in both the encode and decode methods, any time I made a change to one method chain, the other would break.

After working on this for a bit, I realized that a ‘phrase library’ store made the most sense. Using a hash for the data structure meant I could remove all duplication and condense the phrase library into just one method.

Depending on the operation the user wanted to do, this method could return either an encoded phrase for a character to be encoded, or the original character for all occurrences of a given spam phrase. I’ll come back to this in a bit.

1
2
3
4
5
def library(input) # takes a hash of either { letter: letter } or { message: message } key value pair
  phrase_library = {
    'a' => ["hilarious spam phrase 1 ","mildly alumsing spam phrase 2 "],
    'b' => ["delightful spam phrase 3 ","hackneyed spam phrase 4"],
    ...

3. Preserving Carriage Returns

The last issue was something I dealt with almost as soon as the first version started working. Because the encode operation strips out all spaces in the message so it can iterate over each character and make the substitutions, I was losing any carriage returns the user included in the original message. Since my goal was to preserve the original message completely, including superfluous carriage returns, this wouldn’t do.

To handle this, the program replaces all \n returns with the ♤ UTF-8 character, which is then replaced with spam phrases just like any other character. When decoding, the phrases associated with the spade character are replaced with the spade, then finally replaced with \n characters right before the whole message is restored to its decoded form and output back to the user.

1
2
3
message.gsub(" ","‡").gsub(/\n/,"♤").split("").each do |letter| # replacing all spaces and carriage returns with temp characters
  # encode each individual character of the message
end

4. Random Phrase Selection

Everything was looking good, except for one final problem. If you encoded a message, then added just one more character (or even a short word), it would just append more phrases to the existing encoded message. This wasn’t good enough! Even if you just changed one character, the decoded message should be totally different.

Solving this last problem turned out well. I couldn’t use a random number to select which phrase to use to replace a character, since it would introduce an element of randomness that felt out of place in a formalized cryptography system.

Instead, I relied on an obvious constant – the length of the message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# in initialize, set the message text to @message and set the @message_length_key

def initialize(message_input)
  @message = message_input
  @message_length_key = message.length.to_s[-1].to_i
end

# in the encode method, iterate over each character in the message and replace each with a phrase
  message_length_key += 1 # increment the key for selecting phrases
  message_length_key -= 11 if message_length_key > 9

# in the library method
# if sending a character to the library to be encoded, we need to return a phrase

character = input[:letter] if input[:letter]
if character
  if !phrase_library[character].nil?
    return phrase_library[character][message_length_key]
  else
    return character
  end

# otherwise, we have a message to be decoded, and we need the original character in the key

else
  phrase_library.each do |char,phrase_list|
    phrase_list.each do |phrase|
      message.gsub!(phrase,char) if message.include?(phrase)
    end
  end
  message
end

When encoding, the message_length_key variable is initialized with the last digit of the length of the message. Then, for every character substitution, the key increases by one. Since I only wrote/found 10 spam phrases for each character, a check runs on message_length_key for every loop and reduces the value if it every gets too high.

And that’s it! It was a pretty fun project, and a good excuse to see what some challenges are when developing crytography systems. Plus, writing lots of gibberish turns out to be pretty fun.

The whole thing’s open sourced and up on github here: https://github.com/kamoh/spam-encoder

sign your pitty virtuous checkboox thousands dogs chasing squirrels in TARGET 

dungeons and potlucks i am real person plus homelessness accreditation pine cone living wage certainly, –

bagels, and severe windblown acne. Chris is dead, Job for you! more and bots have been replaced with people new flavor? Pepsi Google told me in whispers the truth savings, a bust iced tea and beverage rappers opportunity of a lifetime, my bagels, and denial of sunrise attack textile gremlins eating more and 

classifieds? Job now on website valley of the getting rich quick was dead? explicit, yet full of romance filed in slowly, all


Creating Cities with Worldview

Worldview is a project I worked on with the inimitable Amber Tunnell, Koren Leslie Cohen and Edward Warren. The idea is to give you an instant snapshot of what it’s like in nearly any city in the world, pulling major news, pictures, weather and tweets related to the location.

The coolest part (in my opinion) is that you can add almost any city you want! Just type it into the input field and the site generates a clock depicting the city’s current local time. When you click the clock, the entire site updates with the city’s info.

The process of adding cities was one of my favorite parts of making this thing, and here’s how we did it.

Frontend Validation

When you first type in a new city, light validation on the JavaScript end checks to make sure what you typed in meets the bare minimum criteria to initiate the API call to Weather Underground – namely that the field isn’t empty and that it doesn’t contain a number.

1
2
3
4
5
6
7
8
9
10
11
12
function submit_new_city(passedInput) {
  if (passedInput !== undefined) {
      var user_input = passedInput;
  } else if ($("#new-city").val() == "") {
      $("#invalid_city").text("Input must not be blank");
      return false;
  } else if (parseInt($("#new-city").val()) * 0 === 0) {
      $("#invalid_city").text("Letters only, please");
      return false;
  } else {
      var user_input = $("#new-city").val();
  }

The optional passedInput argument that the submit_new_city function takes is used to generate the first five cities when you initially load the page, so it can bypass this validation.

API Results Validation

Once the request is accepted past the initial validation, it’s sent via Ajax call to Weather Underground’s awesome autocomplete API. You don’t even have to send the complete name of the city – the API will return the best guess it comes up with! This is undoubtedly useful, but there are still a few wrinkles.

First, we make sure that there’s something in the results array. For example, if you search for New Cheeseburger, you’ll get an empty results array.

1
2
3
4
5
6
7
var i = 0;

function findCityArray(i) {
  if (response.RESULTS.length === 0){
    $("#invalid_city").text("Please enter a valid city");
    return;
  }

Next, the API includes countries as well as cities, so we have to screen for that.

1
2
3
4
5
// continued
else if (response.RESULTS[i].type === "country" || response.RESULTS[i].lon === "-9999.000000") {
  $("#invalid_city").text("Please enter a city and country");
  return;
}

Finally, there are a bunch of edge cases of non-city locations where weather readings are taken, like hospitals and heliports. There are also some alternate names for regions, like Hong Kong S.A.R. (Special Administrative Region), which is a different result than just Hong Kong, China.

To handle a few of these edge cases, we use a basic regex that we update as needed:

1
2
3
4
// continued
else if (response.RESULTS[i].name.match(/(international|hospital|helistop|S\.A\.R|de Olivenca|do Potengi)/i)) {
  return findCityArray(i++);
}

If the initial result isn’t blank, but it doesn’t meet the criteria here, we send another recursive findCityArray call to return the next element in the results API.

Backend Validation

Once we have valid city information, it’s time to hit the server. The aim here is to send the city info to the server via Ajax and create or find a city object that we’ll use to create a new clock that the user can click on.

To do this, we send a POST request to the corresponding controller in Rails, which does exactly this – finding the user (if logged in) and making or finding the city.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@user = User.find(session[:user_id]) if session[:user_id]
@city = City.find_or_create_by(lat: city_params[:lat], lon: city_params[:lon]) do |city|
  city.name = city_params[:name]
  city.bigger_thing = city_params[:bigger_thing]
  city.country = city_params[:country]
end

if !@user #create a temp user tied to session ID
  @user = User.create(name: 'Guest',
      provider: 'anon',
      uid: session[:session_id],
      image: 'https://origin.ih.constantcontact.com/fs197/1110193228531/img/301.jpg?a=1115291249439')
  @user.cities << [City.find(1),
                   City.find(2),
                   City.find(3),
                   City.find(4),
                   City.find(5)]
  session[:user_id] = @user.id
end

Another cool thing here – if the user is not logged in but adds a city, we then create a temporary user and track the different cities they’re using the session cookie. If this anonymous user decides to log in with their Twitter account, we update this anonymous user’s info in the database with their real Twitter info and also import his cities from the session cookie into the new user’s account. Edward took the lead on this feature, and you can read more about it on his blog.

In the controller, we also return the ID of the clock to be removed (del_city_id) from the page to make room for the new one.

Finally, there’s one last bit of validation: If the clock is already being displayed on the page, we show an error message to this effect and don’t update the page.

1
2
3
4
5
6
7
8
unless @user.cities.find_by(lat: city_params[:lat], lon: city_params[:lon])
  @user.cities << @city if @user
  del_city_id = city_params[:lastClock].to_i
  CityUser.find_by(user_id: @user.id, city_id: del_city_id).destroy if @user
  render json: @city
else
  render json: "this city already exists".to_json
end

Otherwise, we return the city object back to JavaScript, call the makeClock function to create the city’s clock, and we’re done!

The four of us presenting the site at QueensJS!

Binary Search Trees in Ruby

There’s never a lack of options for ways to store data. Depending on the type of data you’re dealing with, you could do much worse than a binary search tree.

The concept behind binary search trees is simple.

  1. The tree is node based, and a new tree is initialized with a root node. This node has a value, a left space, and a right space. Both left and right spaces are empty to begin with.

  2. When you want to add a new node, the tree compares the value of the new node to the value of the root node.

  3. If the new node’s value is less than the root’s value, it’s stored in the root node’s left space. If there’s already a node there, then compare against that node and repeat.

  4. If the new node’s value is greater than the root’s value, it’s stored in the root node’s right space. If there’s already a node there, then compare against that node and repeat.

That’s it!

Things get a little more complex once the tree starts to fill out, and the algorithm has to continue traversing down each branch of the tree to find the perfect spot for your new node.

There’s also the question of inserting nodes with duplicate values. While it’s strongly recommended to exclude duplicate values from a binary search tree, you can elect to store them to the left (by allowing less than or equal to nodes) or right (by allowing greater than or equal to nodes). If you do allow this, you run the risk of creating an unbalanced tree with different numbers of branches on either side.

One way of implementing binary search trees in Ruby is with two separate classes: one for the tree itself and one for the node objects that populate it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class BST

  attr_accessor :data

  def initialize(data)
    @root = Node.new(data)
    @sorted_data = []
  end

  def insert(val)
    @root.insert(val)
  end

  def traverse(node=@root)
    traverse(node.left) if node.left
    @sorted_data << node.data
    traverse(node.right) if node.right
    @sorted_data
  end

end

class Node

  attr_accessor :data, :left, :right

  def initialize(data)
    @data = data
    @left = nil
    @right = nil
  end

  def insert(val)
    new_node = Node.new(val)
    if new_node.data < data && left.nil?
      self.left = new_node
    elsif new_node.data < data
      left.insert(val)
    elsif right.nil?
      self.right = new_node
    else
      right.insert(val)
    end
  end

end

As you use the insert method on the tree to add new nodes, it filters down to the insert instance method on the root node, then recursively calls itself on each child node as it searches for an empty place to attach the new node to the tree.

The traverse method also uses recursion to visit each node and add their values to an array, starting down the left-most node at the bottom of the tree and working its way over to the right-most node.

Binary search trees perform relatively well, with average time complexity of O(log(n)) for all operations and O(n) at their worst.

However, since the shape of the tree is wholly dependent on the order that new nodes are added, the overall structure of the tree may degrade over time after numerous deletions. Also, since tree traversal requires comparisons against each node, very large trees may rack up longer search times.


Utterly Insane Data Structures

The process of learning something completely new is a strangely tiered experience. More than anything else, the past seven weeks have felt like falling down a very deep pit, and gradually climbing out. The tricky part is, since you’re so focused on climbing up, you can’t actually tell when you’ve climbed past where you fell in – all you know is to keep going.

Once you get into this groove, it can start to feel comfortable. On the other hand, staying humble and keeping a beginner’s mind is paramount to staying receptive and curious.

Which brings us to data structures!

At this point, I’ve grown comfortable using the common data structures used in software. Arrays, hashes (objects in JS), stacks and queues seem like reasonable enough entities. Even binary search trees make sense, despite being more complicated to wrangle.

Which led me to thinking – are there any stranger data structures out there? Could there be odd classifications of information out there in the wild, their mysteries coiled tight inside dense documentation, waiting to be stuffed with bits?

Of course there are – this would be a pretty short blog post if there weren’t!

Bloom Filters

The bloom filter is almost exactly what I was looking for – a bizarre, ungainly data structure with plenty of good points, and a few dashes of tragic weirdness.

Bloom filters bring a heaping helping of optimization to the table. Instead of storing long chunks of data verbatim into a hash table or some other literal configuration, they hold values in multiple places in memory in order to check for ‘set membership,’ or whether your queried item belongs in the particular set being searched. This cuts down significantly on the memory required to store the structure, as well as the number of queries needed to find the result.

When you want to access a value, the bloom filter will check all of the memory locations associated with that search term, and if the return values are positive, it’s a good indication that it exists.

Unfortunately, because memory locations are reused by multiple entries in the filter, it’s possible to generate false positives depending on how many values are being stored.

Oh, and you can never delete anything ever, because the memory locations corresponding to the term may be in use by other values. So weird!

So what the heck do you use this for? Until about two years ago, the Chrome browser used a bloom filter to detect malicious URLs. On the other hand, as of February 2014 Google appears to still use bloom filters to collect metrics stored from users.

For more clarification, Cube Drone has a pretty good three.5 minute summary of how these things work:

Tries

Pronounced “tree” (see? weird right off the bat), tries appear to ape the structure of binary search trees, but they’re unique animals. While binary search trees reshuffle themselves to accommodate new values with respect to the current makeup of the tree, tries traverse an existing selection of data to return a specific value – which is where they get their name, from reTRIEval. Tries also specialize in text queries, which comes into play regarding their real-world use cases.

And because they are used to retrieve values instead of generating an updated order, they offer a space-saving alternative to hash tables and other basic data indexing structures.

So how do they work? Given a list of words that all start with the same few letters – like ace, actor and aces – the trie would list utilize a separate node for every letter, following all the way down until each traversal terminates in a final word.

If you’re thinking that something like this would be good for spell-checking or autocomplete, you’re right! Tries are generally used for such text-intensive scenarios.

rabblerabbleRubble on YouTube breaks down the concept in under two minutes:

Skip Lists

Skip lists are the coolest things in the world. Skip lists provide fast searching capabilities within an ordered series of elements, commonly numbers. In essence, skip lists compare a current element with other elements you’ve previously inserted into your collection – including not only INFINITY on the right, but NEGATIVE FREAKING INFINITY on the left!

Once you’ve slotted where an element is supposed to go, the element may or may not be ‘promoted’ up to the next level of comparison based on a random decision by the search algorithm. Since some numbers don’t get promoted, future selections can skip entire swaths of set data, speeding up the entire query time – thanks to the flip of a coin!

In other words: Skip lists don’t care about what you just did. Skip lists don’t care about your plans for the future of your little algorithm. Skip lists are gonna do skip lists just how skip lists likes it.

Skip lists are so cool that this video showing them in action, even though the narrator’s voice is literally skipping because he set the speed too fast and the visual quality is near-abysmal, is by far a better explanation than any words I could provide.

Watch, enjoy – and learn.


The Curious Chairs of the Flatiron School

The first time I walked into The Flatiron School, I thought to myself: “What are these crazy orange things?”

I had come to one of the weekly NYC on Rails meetups in December of 2013 to check out the vibe and decide if I wanted to apply to the school’s web development program. Strewn about the main meeting space were knee-high, accordion-esque bright orange… things.

Were they chairs? Were they stools? Were they the missing business ends of giant toddler-sized toy hammers?

Spoiler: They turned out to be chairs. Ergonomic chairs, in fact, created by designer Alan Heller. The ErgoErgo chairs (as they’re officially called) were designed to encourage active sitting, relying on the sittee’s core muscles for stability as you rock gently back and forth.

Once I had gotten used to the concept, using the chair turned out to be fun in its own novel way. Figuring out how to best use the chair added a playful dimension in talking to the other meetuppers, helping ground the evening in a more open-minded mood.

Now that I’m a full-time student at Flatiron, I’ve noticed how easily my classmates have incorporated the chairs into their routines. Since they’re so modular and light, it’s easy to grab a few and turn any table into a lunch spot or meeting area, use one as a footrest, or even corral a bunch into a nifty nap corner. In just a matter of weeks, the ubiquity of these strange little chairs had become a given.

Cool, right? There’s something else entirely that explains why these peculiar little chairs fit in so well here – and it’s because the entire process of encountering, evaluating, interacting and experimenting with them is a perfect metaphor for learning to program.

Upon first glance, ErgoErgo doesn’t look like any chair that belongs in an office setting – there’s no back, they’re too short, the shape is wrong, the color is far too bright – and you’re immediately thrown out of your comfort zone, just as someone new to programming is quickly buried in confusion.

Then, as you figure out that it’s just another type of chair, you try sitting on it and gradually learn how it operates – how much rocking you like, how much give each side allows, etc. This is analogous to the long acclimation phase of learning to program – deciphering what error messages mean, how data structures behave, what kind of commands are expected, and so forth.

Finally, as you accept ErgoErgo’s new definition of what a chair can mean, you grow comfortable in its use – turning something that was strange and unfamiliar moments ago into something you totally understand. It goes without saying that the programming equivalent to this stage is rather long, but the metaphor is already complete. Something that once beguiled you as intimidating or impossible is now something eminently knowable, with time and experience the only obstacles to an increased understanding.

The entire process of encountering, evaluating, interacting and experimenting with them is a perfect metaphor for learning to program.

A major part of becoming a programmer is mental. The mental shift from “I need a programmer to help me” when faced with a technical problem to “I can figure this out” is an important one; the transition from being frustrated with code defects to being driven by curiosity to find the problem is critical in staying motivated to improve.

As much as I may be reading into this, and as off-the-wall a metaphor it may seem, having these odd chairs around as I’m trying to mold myself into a programmer is a constant reminder that what may seem unfamiliar and alien one day may become familiar, welcome and fun the next.


Named Parameters: What’s A Nice Keyword Argument Like You Doing in a Place Like This?

In one of the labs from a few weeks ago, my Ruby class was introduced to named parameters, also known as keyword arguments. These parameters are defined in the method signature with a default value in the format (named_parameter: default_value).

Because their behavior appears similar to standard arguments with default values, most of us were mystified about their purpose. In Ruby, standard arguments with default values appear in the format (standard_argument=default_value). Take a look at the similarities:

1
2
3
4
5
6
7
8
9
10
11
12
13
  def drink(spirit: "whiskey") # spirit = named parameter
    "Another #{spirit} for my friend here, barkeep."
  end

  drink
  #=> "Another #{spirit} for my friend here, barkeep."

  def eat(snacks="pretzels") # snacks = standard argument with default value
    "And some #{snacks} - I'm famished!"
  end

  eat
  #=> "And some pretzels - I'm famished!" 

As beginners, was there some use for them we just weren’t grasping? Or were these named parameters just another option bestowed by the Ruby gods in order afford us more options when coding?

Looking at this in another perspective, if you try to call a standard method with arguments without using any, you get an error:

1
2
3
4
5
6
7
8
9
  def drink(container)
    "Pour me a #{container}, willya?"
  end

  drink("glass")
  #=> "Pour me a glass, willya?"

  drink
  #=> ArgumentError: wrong number of arguments (0 for 1)

It’s logical to assume that named parameters would work the same way. Yet if you try this with a method with named parameters, it still runs – just like how standard parameters use default values for missing arguments!

While this is helpful to have, it’s nothing that we can’t do through default parameters.

Then we learned that named parameters don’t care about the order in which you call them.

On one hand, neat trick!

1
2
3
4
5
6
  def bootlegger(distillery: location, source: location)
    "We smuggled the bourbon from #{source}, but we brewed this moonshine in #{distillery}. Dee-licious!"
  end

  bootlegger(source: "Canada", distillery: "Grandma's old bathtub")
  #=> "We smuggled the bourbon from Canada, but we brewed this moonshine in Grandma's old bathtub. Dee-licious!" 

On the other hand, who cares? This feature is a nice wrinkle, but it doesn’t really seem like it warrants the existence of the function.

After a little digging and experimentation, I finally found a reason why named parameters are worth the trouble: They allow methods to require specifically-named parameters when being invoked, for an added measure of security!

Source: Flickr

1
2
3
4
5
6
7
8
9
  def speakeasy_knock(password: )
    "'#{password}'? Good enough for me, come on in!"
  end

  speakeasy_knock
  #=> ArgumentError: missing keyword: password

  speakeasy_knock(password: "Open up, chump!")
  #=> "'Open up, chump'? Good enough for me, come on in!" 

Of course, you’ll need added security measures beyond just requiring the named parameter. But suddenly, having named parameters available as a tool starts to make sense.

Because standard arguments take input regardless of typing or designation, and because default arguments are fine not taking any input from the method call at all, requiring a named parameter for a method to function gives it a measure of protection against reckless usage.

To strain an already-exhausted metaphor, in certain use cases, named parameters can act exactly like locked doors that require code words in order to grant entry.

Source: Speakeasy216

For more gory details about this and other functions introduced in Ruby 2.0.0, check out this substantial post by Marc-Andre Lafortune: http://blog.marc-andre.ca/2013/02/23/ruby-2-by-example/


Why Learn to Program?

Starting on the first week of June, I’ll be starting as a web development student at the Flatiron School. The course is full-time intensive, meeting every day from 9-6 for twelve weeks. Students enter as programming newbies and leave as employed, full-stack web developers.

Since graduating from college, I’d been working in the video game industry as a designer and producer. So why the switch to programming?

I’ve always been interested in how computers work. Though I’ve long messed around with light coding, websites and scripting here and there over the past ten years, I’ve never sat down to formally learn it (aside from two poorly-taught classes in high school and college). After a friend of mine went through Flatiron’s program, his constant praise for the experience piqued my interest, and after getting accepted, I decided to go.

However, curiosity in programming is more than just a long-time interest. The world today runs on software, especially over the web. If you’re able to not only understand how the web works, but capable of creating your own tools that leverage it, you wield immense power. I’ve always valued being a creator over just being a consumer, and the knowledge I hope to gain from this class will push me even further to the former.

Over the course of the class, I’ll be posting updates and thoughts in this blog. It’s going to be an interesting summer.