Ruby, etc

Learn all the things

He who enjoys doing and enjoys what he has done is happy. - Fortune Cookie

What I Wished I Knew

A few things I wish I knew when I started my career as a software developer.

Go to User Groups! I was working for 2-3 years before I got the courage to go to my first user group. Now I currently run one, and have in the past run more than one. Get out there and meet people, if it is a long commute to the meeting or you have little kids at home (often an excuse/reason I hear) then maybe only go every 2-3 months. It is a sacrifice you must make for your career.

This one has occasionally blocked me: The language you did when you started doesn’t have to be the one you are doing now. People change and the language they used at one time (PHP) may not appeal to them anymore and IT IS OK TO CHANGE. And when you do, you don’t need to make a big deal about it. I’ve seen some recent “I’m done with ruby! and here’s why it sucks” posts. If you are done with Ruby, then fine.. just go :)

Also I have spend too much time focusing on one language (Clojure) and looking for jobs that just aren’t there..and being super disappointed when I couldn’t get a job. Bummer. More then once I set aside all other things to study and also donated to kickstarters that were Clojure focused in hopes I can help progress the language. I think i have been to more Clojure conferences then Ruby/Rails!

I see friends/associates of mine that are relentless on making their favorite language do things that maybe is not best, when other languages are better. It is such a waste of time, energy and resources. So don’t get too tied to the langauge because it may not be best for all things. Learn the principles and concepts of a language so learning another is just a matter of syntax and idioms.

I hoped I made you think about a few things and maybe save you some disappointment. What did you learn that you wished you knew when you started?

Interview Prep

I recently went through this process so I thought it would be good to share what I think are good things to do to prepare for an interview.

Logistics

Arrive early, sit in your car or outside and walk in 15 mins before (I’m kind of paranoid, so I get there 30 mins before usually). Ask me about a job I didn’t get (years ago) because I was late. Hey, I had a good reason, they changed the time on me and mentioned it an attachment (not the body of the email) that I didn’t notice was there. To help with miscommunications, email your contact the day before and confirm time, date, place. Ask about parking or landmarks around the office so you can be sure you are in the right place.

Bring a bottle of water. It’s crazy, but sometimes you are not offered a drink! Always good to bring some just in case.

Bring some printouts of your resume just in case. One of the last interviews I had, they had printouts of what was on linkedin which was a more abbreviated version of my resume. Don’t know why they didn’t have my actualy resume, but I immediately regretting not having print copies. In the past I’ve had a nice folder for my resumes and pen too like this leather portfolio.

Dress up, at least with nice pants and a shirt. I think the only time I wore jeans to an interview is on a second interview when I saw around me everyone was in shorts the first time. While you are there, glance around to see how everyone else is dressed so you know what to wear on your first day. Bring a sweatshirt/jacket in case it’s cold in the office.

Expectations

Make sure you tell the recruiter or initial interviewer what you want to do. You wouldn’t believe it this, but one job I said I wanted to do Ruby and after 4 hours and 9 people, they told me they didn’t have that much ruby. I was pretty mad to have my time wasted.

Or another time, someone comes recruiting at a cojure conference, I do a code challenge (in clojure) and interview for 4 hours (including 30mins talking about my clojure code challenge) … only to have them say I was too specialized and they want someone to do python and Go. Also a frustrating experience! If they would have only asked me, “hey you are great on clojure, but how do you feel about go and python?”.

One more… one place they wanted ruby and I talked about my 11 years of Ruby and also 4 years ago I also started learning clojure for new challenges. He didn’t continue the interview process, afraid he’d hire me and I’d leave for clojure. Well, sorry for being a polyglot! I’m hoping this was just a rare case and not everyone is so narrow minded. Also, there are no clojure jobs in Austin (everyone who does it in Austin is remote!).

Yep, next interviews I clarified what I wanted to do and what they needed and tried to gauge how they felt about being a polyglot..

Coding

I know you might not use Big O Notation and analysis In Real Life very often, so even I forget it form time to time. But when you are set to start interviewing, learn it or review it.

Do some exercism or codewars exercises to review for the language you think you will be tested on. Find a friend and do some pair programming so you can get the hang of talking about your code as you write. Practice setting up a project. I remember doing a couple new Clojure apps and setting up a library and the tests for the library and getting all the paths and names correct. With ruby, setup a new project and install minitest and make sure you can make a module and a test and it just works.

Google ‘list of questions to ask at an interview’ and get some ideas. One question that I found in that manner is asking your interviewer “What challenges do you think I will face in this position?” which revealed a little more about the position than I knew before.

Don’t complain about your last job(s) .. it doesn’t matter at this point and you don’t want to look like you are a whiner. If they ask why you left your last job, go ahead and say why but keep it to facts not emotion.

Hopefully these will help you land your next job .. Do you have any tips?

Coding on Car Trips

I have a big family scattered through the United States, so we do road trips. My husband drives while I code :) On my last road trip I wrote these notes:

Bring some things to do that don’t require wifi. If you have a codeschool account, download some of the videos to watch. You may not have the bandwidth to do the exercises and play along but you can at least watch the videos.

Plan on sitting in the back of the car/van so you can be away from the front windows – it can be so bright! it makes it hard to see the screen. For my Expedition I have some window cling screens to block the bright sun (and keep it cooler in the back!) and it works pretty well.

Bring an extra laptop charger. I usually travel with two, one in my bag and one in my suitcase. Because of that ONE time I left my charger in the hotel and I needed it for a presentation! When I am in the hotel I use the one in the suitcase, other places I use the one in my bag. Same goes with other chargers (phone, ipad etc).

I have this adapter to plug in my laptop and my usb cables.

Use your Ipad (or other tablet) to read tech books or look up code. To that end, get some good books, you can use search and it is almost as good as looking up docs online.

Listen to Podcasts. Here’s a list of my favorite podcasts. Just make sure to download them ahead of time if you are in the waste lands of West Texas where they don’t have cell phone towers.

Koans, I have a list of koans which are small tests to complete to help you learn coding.

Brainstorming, you may find the somewhat quietness of a roadtrip to be a perfect time to brainstorm and come up with ideas.

Happy Travels

Tagging in Robot Framework

I talked about the awesome robot framework in the previous post and I wanted to talk about Tagging since I think this is very useful.

Tagging is one way to group tests so you run a subset of tests. In your test case, add this:

1
2
3
4
5
Homepage Loads
  [Tags]  smoke
  Open Homepage
  Element Should Be Visible  ${FIND_LOGO}
  [Teardown]  Close Browser

Results to run just one tag:

1
2
3
4
5
6
7
8
9
10
11
12
▶ robot --include smoke youtube.robot
==============================================================================
Youtube :: A test to demo testing YouTube
==============================================================================
Homepage Loads                                                        | PASS |
------------------------------------------------------------------------------
Search Loads Results                                                  | PASS |
------------------------------------------------------------------------------
Youtube :: A test to demo testing YouTube                             | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================

You can create a focus so it is easy to run that one test as you are developing it. I have used a similar technique when working on rspec tests. When the test works as you wanted, remove the focus tag. :)

When you look at the report you can see the tags assigned to teach tests. This report was run on all tests. Screenshot

Automation Testing With Robot Framework

On one of my projects recently, I was tasked with finding an automation framework. Looking at my options..

  • Cucumber (ruby, although other languages could be used)
  • Capybara / Rspec (ruby)
  • Robot Framework (python)

All of the options for web testing use either Selenium or Watir. I have only did a little with Watir, so I focused on something with Selenium for my first pass of experimentation.

I love testing if you know anything about me, I’m nuts about testing. Front End Testing however has been fruitless IMHO .. until a few years ago I discovered page objects and it became tolerable to do frontend testing. My projects changed and I didn’t really do much for a few years with web frontend testing.

Recently I have been looking into Python and discovered Robot Framework, meant to test a variety of things in addition to the web. The Selenium2 package is especially nice.

You can have a robot script as a text field, in a TSV, or other types of strutured text. I find the text file works for me.

Here we can define a Test Case:

1
2
3
4
Homepage Loads
  Open Browser  https://www.youtube.com  Firefox
  Element Should Be Visible  id=yt-masthead-logo-fragment 
  [Teardown]  Close Browser

This script opens the browser to youtube using firefox. Then checks that element located by id=yt-masthead-logo-fragment is visible (ie on the page, not display: none).

you must make sure to have two spaces between the elements

Open Browserhttps://www.youtube.comFirefox

Or it won’t be able to parse. I guess this is when having it in a spreadsheet (TSV) would come in handy. But it’s not too bad to get the hang of. Plus if you use nice editors like PyCharm and the Robot Framework Plugin, it has nice syntax highlighting for you.

Running the test case like this:

1
robot youtube.robot

And results look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
▶ robot youtube.robot
==============================================================================
Youtube :: A test to demo testing YouTube
==============================================================================
Homepage Loads                                                        | PASS |
------------------------------------------------------------------------------
Youtube :: A test to demo testing YouTube                             | PASS |
1 critical tests, 1 passed, 0 failed
1 tests total, 1 passed, 0 failed
==============================================================================
Output:  robot-demo/output.xml
Log:     robot-demo/log.html
Report:  robot-demo/report.html

There that is just a taste of what it can do. If you want to see what all you need installed you can see my robot demo and some more complex tests. More testing posts to come on this, I think this is a very excellent framework … even if it is not ruby :)

My Favorite Tech Podcasts

I saw someone asking about tech podcasts recently and I named off a few, but I think it is easier to put it in a blog post :) Ordered in roughly the order I am into at the moment :)

General Tech

  • The Changelog - open source discussions, interviews with a wide varity of languages
  • DotNetRocks - You might think it is all about .NET but it is not, they cover a wide variety of topics.
  • Functional Geekery - Wide variety of topics on Functional Languages.

Testing

Python

Clojure

  • defn podcast - The hosts are hillarious on this podcast and I enjoy the banter, mostly interviews with clojure developers
  • Cognicast - Hosts are from Cognitect, the “stewards of the clojure language”.

Elixir

Ruby

  • Ruby Rogues - I listen sometimes, I generally browse the topics to see if it looks interesting.

Game Development

Misc

  • Two Keto Dudes - About the Keto way of eating. BACON BACON!!! Also I am a bacontarian. :)
  • Into The Nexus - About Blizzard’s game Heroes of the Storm

Using Jshint

Javascript. It’s a language that some of us love to hate, me occasionally. Here’s a few notes to myself to make JS a little better :)

Use these settings in JSHint to avoid instanity:

1
2
3
4
file: .jshintrc
{
  "flagname" : true
}

If you have settings that apply to only your test environment you can put those in test/.jshintrc (maybe allowing global var for your test function) .. you can extend a confiuration in another file with this option `”extends” : “../.jshintrc”

Sometimes you just can’t please everyone, including the linter. Here’s how to ignore blocks or lines from the linter:

To ignore a block of code use

1
2
3
/* jshint ignore:start */
myBadJsHere
/* jshint ignore:end */

to just ignore a single line:

1
myBadJsHere // jshint ignore:line

Obviously you shouldn’t let the linter ignore code but you may have a good reason to do so.

Handy thing to have in your .jshintrc file:

eqeqeq

1 != “1” right? comparing a number to a string? no, JS says sure its the same using automatic type conversion. Use this flag to warn you and remind you to use triple equals to not do automagic type conversion.

Switch statements

This was just a neat thing I learned today, in JS switch/case statements you need to do a return or break or you will fall through to the next option. Leave a note for the next guy that says you did mean to fall through with a comment /* falls through */ and you will silence the warning from jslint. Kinda cool, huh?

Use Strict

"use strict";

This tells javascript to cut the funny business and not be so helpful and error when stuff should error.

I picked up some of these tips watching Pluralsight: JavaScript Best Practices

Thanks for humoring me as I write these notes to myself :)

Ruby Like Python

I did python.. awhile back, it was like ruby in some ways and in some ways not. So I picked one, I went full blown into Ruby. Recently I’ve seen lots of job postings for Python so I figured I’d give it another go :)

Slicing

In Python:

1
2
3
4
5
6
7
>>> message = "hello world"

>>> message[0:5]
'hello'

>>> message[6:]
'world'

Then in ruby

1
2
3
4
5
6
7
8
2.4.0 :001 > message = "hello world"
 => "hello world"

2.4.0 :002 > message[0..5]
 => "hello "

2.4.0 :003 > message[6..-1]
 => "world"

Eveything in ruby is an object and objects have methods. String has a method slice, aliased to [] (cool!) and the .. is a range. You could use a comma but there is so way to tell it to use the end unless using a range. If you look at the params for the slice method it is a fixnum or fixnum, fixnum or a range. It can also take a string (if you use the method name) but that is a strange use.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
2.4.0 :005 > message
 => "hello world"

2.4.0 :006 > message.slice("ello")
 => "ello"

2.4.0 :007 > message
 => "hello world"

2.4.0 :008 > message.slice!("ello")
 => "ello"

2.4.0 :009 > message
 => "h world"

Unless you use slice! (bang) does it actually change/do anything remotely interesting. Probably I would find a more clear way to do it than using slice with a string.

Well this is just one aspect of the differences and I am not sure if there are differences in the versions of python too.

Setting Up a New Ruby or Rails Project

A checklist to follow when starting a new project if you are using rbenv or rvm:

Make sure this is in your .bashrc or .zshrc

1
alias be="bundle exec"

Then any time you would need bundle exec you can just use be. Or alternatively, Hal Fulton pointed out you can do bundle exec bash to get a bash shell that would be the same as using be each time :)

  1. Create a directory for your project and change into it.
  2. Create a Ruby version file: echo "2.4.0" > .ruby_version.
  3. Change out of directory and back in, and ensure your version of ruby is correct with ruby -v.
  4. Make sure Bundler is installed: gem install bundler.
  5. Create a Gemfile bundle init.
  6. Setup git repo with git init.
  7. Create a README file and put the name of your project and what it is used for.
  8. Add all files git add ..
  9. Commit git commit -m "inital commit".

Then if you are making a ruby gem:

  1. Use bundle gem myawesomegemor do it by hand (helps you to remember.. hehe)
  2. Create a gemspec touch myawesomelibrary.gemspec.
  3. Make directory: mkdir lib.
  4. Make library file: touch lib/myawesomelibrary.rb.
  5. Make test directory: mkdir test.
  6. Make test file: touch test/myawesomelibrary_test.rb.

Gem spec template:

1
2
3
4
5
6
7
8
9
10
11
12
13
Gem::Specification.new do |s|
  s.name        = 'myawesomelibrary'
  s.version     = '0.0.0'
  s.date        = '2017-01-01'
  s.summary     = "My awesome library summary"
  s.description = "My awesome library description"
  s.authors     = ["Awesome Programmer"]
  s.email       = 'myself@awesomeprogramming.com'
  s.files       = ["lib/myawesomelibrary.rb"]
  s.homepage    =
    'http://rubygems.org/gems/myawesomelibrary'
  s.license       = 'MIT'
end

If you are making a rails app:

Add the version of Rails you want to use to the Gemfile ie: rails "5.0.1" and bundle install. Then do rails new . to create a rails app with the same name as current directory.

Records in Clojure

I haven’t used records before in a project and when reading some code that used it, realize I really need to learn about records. It’s not complicated and actually kind of cool! Here’s my experimentation.

To start off, I re-read the first chapter in ClojureApplied where it talks about Modeling your Entities.

I took a familar problem, my recipe-api. This is a recipe api that uses liberator api reading recipes from a database. But, I can use the concept here.

1
2
user=> (defrecord Recipe [name link source])
user.Recipe

When you create a record, you get two factory functions for free to create instances of it. The first, a positional function:

1
2
user=> (def tacos (->Recipe "Tacos" "www.tacorecipes.com" "mom"))
#'user/tacos

You must put values for all the fields in or you get

1
2
3
user=> (def tacos (->Recipe "Tacos" "www.tacorecipes.com"))

CompilerException clojure.lang.ArityException: Wrong number of args (2) passed to: user/eval10000/->Recipe--10017, compiling:(form-init4856550892047924668.clj:1:12)

The other way you can create an instance of a record is using a map.

1
2
3
4
user=> (def pizza (map->Recipe {:name "Pizza" :source "dad"}))
#'user/pizza
user=> pizza
#user.Recipe{:name "Pizza", :link nil, :source "dad"}

We didn’t have a value for link in the map so it still let us create the instance and automatically assigned the value of nil. This might be a reason to use the map-> version over the positional version, if you don’t know all the values at that time. They work like maps, you can add in missing values later with assoc:

1
2
user=> (assoc pizza :link "www.pizzarecipes.com")
#user.Recipe{:name "Pizza", :link "www.pizzarecipes.com", :source "dad"}

Accessing the the values in a record is just like a map:

1
2
3
4
user=> (:name tacos)
"Tacos"
user=> (:source tacos)
"mom"

The chapter has a great section on why you would want to choose Records over Maps you should read! I won’t spoil the fun here, but there are some compelling reasons when to use records over a map.