You're viewing all posts from 2018. Check out the archives for more.

Annual Review: 2018

Much like Nicholas Felton's totally awesome and inspiring Annual Report, I've always wanted to write up a personal year-end summary of the things that I did, consumed, and accomplished that year. Below is my first attempt, which summarizes 2018. Hopefully I keep up this tradition and, 60 years from now, my kids have many of these to read.

Films Watched

I saw 52 films this year. That’s a far cry from my pre-kiddo life when an average year busted into triple digits. Alas, I’ll take 50+ as a solid win.

Below is a breakdown of the film ratings that I doled out in 2018:

Of the films that I saw this year, below were my top 10 (in order of preference).

  1. Call Me by Your Name (released in 2017) 

  2. Roma (2018)
  3. The Wolfpack (2015)
  4. Phantom Thread (2017)
  5. Eighth Grade (2018)
  6. Dina (2017)


  7. A Most Violent Year (2014)
  8. Restless Creature: Wendy Whelan (2016)


  9. Lady Bird (2017)
  10. Filmworker (2017)

TV Shows Watched

In 2018 I saw one or more seasons of 17 television shows, about half of which were based on documentary-ish shows (i.e., mostly-non-scripted, based on a true events).

Each show that I watched in 2018 is listed below (in order of preference):

  1. Wild Wild Country

  2. The Vietnam War
  3. The Fourth Estate
  4. The Staircase
  5. The Deuce
  6. Making a Murder
  7. The Romanoffs
  8. The Zen Diaries of Garry Shandling
  9. Wormwood

  10. Big Little Lies
  11. American Vandal
  12. Crashing
  13. Easy
  14. Evil Genius
  15. Big Mouth
  16. Schitt's Creek
  17. The Good Place

Music Listened To

According to Spotify, I listened to 16,190 minutes of tunes this year (though, as I write this, there are still some days left in 2018).

My most listened to artist was Drake at 28 hours, followed by SZA, Hayden James, Kacey Musgraves (who liked one my tweets!), and Dawn Golden.

My most listened to individual songs were (in order):

  1. NUMB by Hayden James

  2. Nonstop by Drake
  3. Just A Lover by Hayden James
  4. Doves in the Wind by SZA
  5. Space Cowboy by Kacey Musgraves

Below are my favorite newly discovered artists from 2019 (in order of preference):

If you’re into this sort of thing, dig into this Spotify playlist which is comprised of the tunes I listened to most in 2019.

Podcasts Listened To

We are probably living through the golden age of the podcast -- there's so much great, and incredibly targeted, content to choose from. Of all the different mediums listed above, I probably consumed the most content from podcasts this year. 

Below are the weekly/monthly-produced podcasts that I frequented the most in 2019 (in order of preference):

In addition, below are the season-based/single-run podcasts that I completed this year (in order of preference):

Weight Loss

I had an epicly awesome year on the scale! On January 1st I weighed in at 184 pounds -- oof. On December 31st: 164 pounds. I lost 20 pounds exactly in 2019!

How did I do it? I ate less food. Like, a lot less.

Losing the first 10-12 pounds was not terribly hard. I aimed to eat 1,200 calories per day, and usually 90% of those calories came from one large meal (almost ways dinner). Other than coffee in the morning, I mostly fasted all day until dinner, skipping breakfast and lunch. The weight came off quickly.

Once I got to 170 or so pounds, I stalled big time -- eating less no longer resulted in pounds lost. That’s when I started doing full or multi-day fasts. I wrote about my longest fast (three days) in this blog post. Through out the year I completed a few fasts, each between one and three days long. This approach got me down to 164 pounds.

My goal for next year is to get down to 157 pounds. That’s only seven more pounds, but losing any additional weight at this point is incredibly hard. The obvious next move is to start exercising (yuck!), which I’ll probably end up resorting to in 2019 to hit my goal weight.

Places Traveled

I traveled to 13 places in 2018. Most of them work-related (I do a lot of onsite trainings for Onit clients all over the world) -- a few were family trips.

Below are all of the places that I traveled this year (listed in no particular order):

  • Mumbai and Pune, India (pic)
  • Belfast, Northern Ireland (pic)
  • Abbott Park, Illinois, USA
  • San Jose, California, USA
  • New York, New York, USA (twice) (pic)
  • Newark, New Jersey, USA
  • Austin, Texas, USA
  • Atlanta, Georgia, USA
  • Philadelphia, Pennsylvania, USA (pic)
  • Boston, Massachusetts, USA
  • Cincinnati, Ohio, USA (pic)
  • San Antonio, Texas, USA (pic)
  • Los Angeles/Orange County, California, USA (I blogged about this trip)

Far and away my favorite trip was to Disneyland with Jeannie and Brighton. The DL is one of my favorite places on Earth (I've gone by myself before, as a grown ass man); seeing it through my two-year-old daughter's eyes was amazing.

Other Tidbits

Below are a few other interesting stats and events from this year:

  • I had 10 cavities filled. Yikes! This will hopefully teach me not to avoid the dentist for three years.
  • Jeannie and I celebrated our five-year wedding anniversary in May. Here’s to 100 more!
  • Brighton turned two in August! Insert obligtory statement here about how fast time is flying by and that she was just born yesterday (all of which is true!).
  • We bought a new house in October (but still haven’t moved into it, as we’ve yet to sell the old house). The house was built in 1935. Just to put that into context, the following events also took place that year: Amelia Earhart became the first person to fly solo from Hawaii to New York; Porky Pig made his debut; U.S. President Franklin D. Roosevelt dedicated the Hoover Dam; and Elvis Presley was born.
  • I moved into a new position at Onit. I now lead our Training & Certification Team, comprised of five rock stars. We did a ton of awesome stuff this year, including a bunch of trainings around the world (see above) and launching an Onit certification program. Also on the Onit-front: I was invited to do the Onit podcast this year -- listen to my episode here.

And that's it! A great year -- here's to an even better 2019!

More Posts About... 2018 / annual review

Disneyland 2018

Up until this vacation, the Powers Family had been on the run, basically driving in the sun, looking out for ourselves (that's number one!). But then, we made a decision, to head back to California, right back where we started from.

And it was epic. We did two days in Anaheim at Disneyland and then a week in Laguna Beach at the Ritz! Here are some of the more choice moments.

A welcoming gift from our awesome travel agent: two delicious Mouse-themed cakes. These were waiting for us in the room when we checked in.

Disneyland: If you buy an $11 ballon, and ask the Ballon Sales Girl nicely, and the line isn't too long, she'll let you pose for this picture.

Disneyland: Brighton was terrified of every character she encountered, evidenced here by her pushing poor Minnie away with great prejudice.

Disneyland: Brighton calmed down as soon as Minnie was a few feet away. She enjoys her life-sized Disney characters at a distance.

Disneyland: We were invited on a tour through Minnie's house. Here's Brighton and I (rudely) examining Minnie's fridge, which was mostly filled with various cheeses.

Disneyland: Cinderella was very friendly. It took me awhile to realize that she was talking to us in character, which led to some akward interactions. I kept asking her questions that only made sense if I was talking to an actress in costume -- she kept responding as the actual Cinderella. Disney fail on my end.

Disneyland: Some people say that Brighton is spoiled. I have no idea what they are talking about. I demand proof!

Disneyland: No trip to the DL is complete without a turkey leg.

Laguna Beach: We had an epic blowout after driving our rental car over something sharp and spikey on the freeway. After one 911 call, a heroic tow truck driver, and an annoying rental car swap out at Enterprise, we were back on the road again.

Laguna Beach: Brighton on the beach. Like Minnie Mouse, she was cool with the water and waves as long as they stayed at a distance.

Laguna Beach: Hanging out by the pool. Brighton is proud of her new cover-up.

Laguna Beach: Sunset in the OC. It's hard to see, but the house in the distance behind us is valued at $45 million.

Airplane Trip: Brighton does very well on planes -- if she has an iPad full of cartoons to enjoy. We bought her unicorn-themed headphones for the flights.

More Posts About... disneyland / family / pictures

My Three Day Water Fast

Three days. No food. Only water. Whoa. This was the adventure that I embarked on from August 18, 2018 until August 21.

But why, you ask? Primarily to lose a few stubborn final pounds. At that point I had lost about 19 pounds in 2018, but I still had seven pounds to go to hit my goal. I had been stalled for a couple of months and I was looking for something new to get me across the finish line.

I never would have tried a three day water fast unless I had heard about it on Kevin Rose's podcast. The idea of fasting always seemed attractive to me, but not eating anything for three days seemed pretty dangerous. After I heard Kevin introduce it as a thing that people did though, that lead me to do some research, and finally convinced me to go for it. In addition to the weight loss possibilities, I was also attracted by the concept of autophagy (which seems valid, but then again, what do I know).

Below is a hodgepodge of thoughts from my experience.

  • Mild initial panic on Day 1. After about 18 hours or so or not eating, realizing that I had another 50+ hours to go I did feel a low-level sense of initial panic. This didn't last long and was very manageable, but if I hadn't done some research before starting I would have probably bailed at this point, fearing that I was about to do some serious harm to myself. Other than this issue though, Day 1 was pretty easy.
     
  • Smooth sailing on Day 2. This was far and away the easiest and best day. I had no mild panic, completely manageable hunger pangs, and an overall sense of "hey, look at me, I'm doing it!". It definitely helped that I dropped three pounds by Day 2.

  • Feeling poopy on Day 3. By the third day I felt pretty bad. When I woke up in the morning I felt weak and light headed, and it was difficult to pay attention to multiple things at the same time (more on this later). It helped though that I was now down five total pounds (in less than three days). On my way to work, with 12 hours still left to go, I definitely considered bailing and calling it quits. Then however, I realized that I hadn't had any water since the night before. As soon as I slammed some water down my throat, I felt better -- not great, but mangeably better. Even so, by around 5pm I had a splitting headache and I was ready for it to all be over.

  • Fast Breaking Meal: I had done a good bit of research about what food to eat when breaking a fast. There was lots of competing advice but I ended up going with fruit and rice cakes. I went to Whole Foods right after work to grab the food and I started eating it before checking out. I probably had about 900 calories and I felt 100% better immediately.

  • Overall it wasn't that bad. The whole process wasn't nearly as bad as you'd think. There were many times when I felt great, in fact -- better than normal. While I found that it was hard to context switch or multi-task (e.g., I had a hard time talking to someone and typing at the same time), I found it easier than normal to deep focus on one particular task. Also, one thing worth noting is that by Day 3 I felt pretty sore inside my stomach and chest -- similar to if I had done a ton of sit ups (that feeling went away within 36 hours of breaking the fast).

  • Final weight loss results: I lost almost exactly five pounds in three days. I'm typing this now four days after the fast ended, and the scale says that I've added back 1.5 of those pounds. As a result then, I probably legitimately lost 3.5 pounds in three days. That may not sound like much, but if you've ever done serious dieting (where "aggressive" means losing two pounds in a week), these results are phenomenal.

    Update (September 3rd, 2019): It's roughly two weeks later now and I'm back down to a full five pound loss from the water fast. Since I broke the fast I've eaten mostly low calorie (though I've had some cheat days). Point being: I think I really did lose (and keep off) a full five pounds from the fast!

  • I'd do it again. Aside from Day 3, the process was pretty darn easy. I do think that I'd do another three day water fast in the future, and next time be more strategic about drinking water as soon as I wake up (and maybe even once during the night). Or, I might only fast for two days next time. Overall though, the whole adventure was mostly postive and worth repeating.
More Posts About... diet / fasting / health

Learning Ruby on Rails: Part I - The Language

Most of my programming experience has been in PHP, JavaScript/JQuery, and VB.NET. When I worked in Support at Code Climate, it became obvious to me that I had picked the wrong languages, and that Ruby was the better choice. With its super simple and legible syntax, Gem support, and stellar framework, I was excited to dig in!

A few years back I dabbled in trying to learn Ruby on Rails, but I made the mistake of trying to teach myself both the language and the framework at the same time. That led to mostly confusion and frustration. I've heard many different opinions on this subject, but I now strongly believe that you should have a firm grasp of the language before trying to learn one of its frameworks.

For the past year or so I've been focusing solely on Ruby, primarily by consuming Team Treehouse's Learn Ruby track. It's a 20-hour course in all and I'm stoked to have finally completed it! Next up: Rails!

While moving through the Ruby course I took copious notes. I thought it would be helpful to share those notes here. Enjoy!

All notes below were written by, based on the Team Treehouse course mentioned above. Red text indicates a key concept.

  • To prompt the user to provide data at runtime, use gets.
  • To execute code within a string, use my_variable = "I am #{code to execute}".
  • In the bullet-point above, using single- (versus double-) quotes around the string modifies the behavior. Double-quotes would run the code in between the { and } characters. Single-quotes would treat everything as a string, without running any code. This is called interpolation.
  • Ruby makes it easy to define a string across multiple lines.

    my_string = <<-HERE
    I am a string
    that is defined across
    multiple lines!
    HERE

  • In the example above, the word HERE could be any string that you like.
  • When defining a string, you can use special characters, such as \n (new line) or \t (tab).
  • Ending a method with a ! changes the original variable. For example, my_string.upcase! permanently modifies the my_string variable. On the other hand, my_string.upcase will not modify the original my_string variable.
  • You can identify what class an object is a member of using object_name.class.
  • Ruby methods must start with a lowercase character.
  • To create a new method, use: def my_method
     # Awesome Code Here!
     # It is common to indent code within a method by two spaces.
     # Not by a tab.
    end
  • The number of arguments that a method accepts is called arity.
  • In IRB, you can load in a file, to leverage its methods and variables. To load a file, use load "./file.rb".
  • The common commenting conventions are to do the following: Use one space between the leading # character of the comment and the text of the comment. Comments longer than a word are capitalized and use punctuation. Use one space after periods.
  • You can increment a numeric variable using my_variable += 1. This works with other operators as well, such -= and *=. This also works with strings, such as my_string += "foo", which would concatenate the current value of my_string with the value foo.
  • Ruby uses the following operators:
    1 == 1 # equals
    1 != 2 # Does not equal.
    && # And
    || # Or
  • Use two spaces per indentation level (aka soft tabs). No hard tabs.
  • To perform an else/if, use the keyword elsif, without the e. You can have multiple elsif statements in the same if block.
  • An alternative to if blocks are case blocks. For example: case answer when "yes"
        puts "Your answer was 'yes'!"
      when "no"
        puts "Your answer was 'no'!"
      else
        puts "Your answer was not recognized."
    end
  • Within an if block, add a ! character to the front of a condition to mean "NOT true." For example, if !(gender == "male). In this example, the condition will be satisfied if gender does NOT equal male. The condition must be surrounded with ( and ) in order to use !.
  • If you use multiple operators on the same line (e.g., variable = 1 + 3 * 3), Ruby uses a precedence system to determine which operators to execute first. The order is anything in parenthesis, then exponents, multiplication and division, and then addition and subtraction.
  • If a method returns a true or a false, it is a standard a Ruby convention to name the method with a ? at the end. For example, def divisible_by_3?(number).
  • Ruby arrays can contain values of different types. For example, you could create an array that contains both numbers and strings.
  • You can also store variables in an array. For example, my_array = [my_variable, "2", "3"].
  • The Ruby equivalent of var_dump or print_r (for an array) is .inspect. For example, my_array.inspect.
  • To create an empty array, use my_array = [].
  • There are a number of different ways to add values to an existing array. For example:
    my_array = ["a", "b", "c"] #Create the array.

    # Add a single new value to the end of the array.
    my_array << "d"
    my_array.push("e")

    # Add multiple new values to the end of the array.
    my_array += ["f", "g"]

    # Add a new value to the beginning of the array.
    my_array.unshift("i")

    # If you inspected this array, it would now return:
    # ["i", "a", "b", "c", "d", "e", "f", "g"]
  • Though the parenthesis are technically optional, it is a standard Ruby convention to include the parenthesis when a calling a method, unless the method doesn't accept any arguments.
  • To get a specific value in an array, use my_array[i], where i is the item that you want. An alternative method is to use my_array.at(i).
  • To get the first item in an array, use my_array.first. Alternatively, to get the last item, use my_array.last.
  • To identify the number of items in an array, use my_array.count.
  • To identify the number of items a particular item exists in an array, use my_array.count("foo").
  • To identify if a value exists in an array, use my_array.include?("foo").
  • To remove the first item in an array, use my_array.shift. Alternatively, to remove the last item in an array, use my_array.pop.
  • A hash can be thought of as an array that stores key/value pairs. Both the key and the pair can be virtually any data type.
  • It is common (almost even standard) for the key in a hash to be a symbol. For example, my_hash = { :name => "jonathan" }. This is because: Using symbols not only saves time when doing comparisons, but also saves memory, because they are only stored once (source).
  • When using symbols as keys in a hash, you don't need to use the => character. Instead, you can use the following syntax: my_hash = { name: "jonathan", sex: "male" }
  • To create an empty hash, use my_hash = {}.
  • To create a hash with items in it, use my_hash = { "name" => "jonathan" }.
  • To retrieve a specific value from a hash, use my_hash["key"] (in this example, the key is a string; if the key was instead a symbol, you would use my_hash[:key].
  • To add a new value to an existing hash, use:
    my_hash = { first_name: "Jonathan" } #Create the new hash and store a single key/value pair.
    my_hash[:last_name] = "Powers" # Add a second value.
  • To remove an item from a hash, use my_hash.delete(:sex).
  • To list all of the keys in a hash, use my_hash.keys.
  • To check if a hash has a specific key inside of it, use my_hash.key?(:key_name).
  • To list all of the values in a hash, use my_hash.values.
  • To check if a hash has a specific value inside of it, use my_hash.value?("Jonathan").
  • A basic loop is:
    loop do
      # Do something.
      # This loop will keep iterating until you press CTRL + C.
    end
  • To break from a do loop, call break.
  • You can put an if statement on a single line, such as: puts "Foo" if x == "bar".
  • An easy way to identify if a particular string exists in a string is using:
    foo = "bar"
    result = foo.index(/bar/).nil?

    # The `index` method returns the index of the first occurrence of the given substring or regex pattern.
    # If the substring/pattern is not found, `index` returns nil.
    # Calling `nil?` returns a boolean indicating whether or not the substring/pattern was found.
  • An example of a while loop:
    x = 0
    while x < 11
      x += 1
      puts x
    end
  • An example of an until loop:
    x = 0
    until x == 100
      x += 1
      puts x
    end
  • To iterate over a hash, use:
    places = {"Houston" => "Texas", "Atlanta" => "Georgia" , "New York" => "New York"}

    # Iterate over the key and the value.
    places.each do |key, value|
      puts key + " - " + value
    end

    # Iterate over just the key.
    places.each_key do |key|
      puts key
    end

    # Iterate over just the value.
    places.each_value do |value|
      puts value
    end
  • You can call the times() method on any integer, which will run a loop that many times. For example:
    10.times do |count|
      puts count
      # count (which is optional) returns the iteration number.
    end
  • The following is an example of a for loop:
    x = 1
    y = 5

    for item in x..y do
      puts item
    end
  • You can also use a for loop on an array. For example:
    states = ["Texas", "New York", "Idaho"]

    for state in states do
      puts state
    end
  • A common Ruby convention is to prefer an each loop to a for loop.
  • There is an important distinction between an each and a for loop. The variables created within a for loop will remain available to you to access after the loop exits. On the other hand, variables created within an each loop will not.
  • When defining a method, you can set default values for arguments. For example, the method below sets c to 25, unless the method's caller explicitly overrides this value.
    def some_method(a, b, c=25)
    end
  • Class names always start with a capital letter. For example, Dog.
  • To instantiate a new object, call Dog.new.
  • It is a Ruby convention to keep class names singular (e.g., Dog not Dogs). In addition, if the class name is two words, do as follows: PromotedEvent (not Promoted_Event or promotedEvent).
  • When you initialize an object, its initialize method is automatically called. For example:
    class Dog
      def initialize
        puts "Woof!"
      end
    end

    my_dog = Dog.new # The string "Woof!" will be printed.
  • To see all methods belonging to a class, call an object's .methods method.
  • You can define instance variables that live within the scope of a class definition. Instance variables will be available to all of the logic defined within the class (e.g., methods in the class can access instance variables). To create an instance variable, define an initialize method at the top of the class. Within initialize define your variables. The name of instance variables always start with @. For example:
    class Dog
      def initialize
        @name = "Fido"
      end
      def greet
        puts "Hi! I'm #{@name}"
      end
    end

    fido = Dog.new
    fido.greet # The string "Hi! I'm Fido" will be printed.
  • Within a class' initialize method, you can define arguments that the class will require during instantiation. Furthermore, within initialize you can set the value of a required argument to an instance variable. For example:
    class Dog
      def initialize(name)
        @name = name
      end

      def greet
        puts "Hi! I'm #{@name}"
      end
    end

    ralph = Dog.new("Jim")
    ralph.greet # The string "Hi! I'm Jim" will be printed.
  • In many cases, you'll want to access an object's instance variables outside of the class definition. For example, sticking with the code sample above, what if you wanted to access a specific Dog's name after you had instantiated it? Based on how the code above is written, you would not be able to just call .name on the object. In this situation, you'd need to use Ruby's attr_reader keyword, as seen in the example below.
    class Dog
      attr_reader :name

      def initialize(name)
        @name = name
      end

      def greet
        puts "Hi! I'm #{@name}"
      end

    end

    ralph = Dog.new("Jim")
    puts ralph.name # The string "Jim" will be printed.
  • When you use attr_reader with an attribute (as seen in code example above), you no longer need the @ character when referring to the corresponding instance variable (assuming you're within the class' definition). In other words, within the class, you can simply refer to name instead of @name.
  • An instance variable that is visible outside of the class definition is called an attribute. For example, in the code sample within the code block above, name is an attribute.
  • For testing/troubleshooting purposes, you can load all code defined within an .rb file right into IRB by simply calling load "./my_file.rb". After doing so, you can then access any classes, methods, or other code defined within the file, right from IRB.
  • Similar to attr_reader, you will also often need to modify a class' attributes. To do so, use attribute_writer within the class' definition. For example: class Dog
      attr_reader :name
      attr_writer :name

      def initialize(name)
        @name = name
      end

    end

    dog = Dog.new("Jim")
    puts dog.name # The string "Jim" will be printed.
    dog.name = "Mike"
    puts dog.name # The string "Mike" will be printed.
  • Within a class' definition, if there are attributes that you will need to both access and modify, you don't need to separately use attr_reader and attr_writer. Instead, you can simply include attr_accessor in the class' definition, which will allow for both accessing and modifying. In other words, attr_accessor combines and replaces both attr_reader and attr_writer. For example:
    class Dog
      attr_accessor :name

      def initialize(name)
        @name = name
      end
    end

    dog = Dog.new("Jim")
    dog.name = "Mike"
    puts dog.name # The string "Mike" will be printed.
  • Within a method definition, the output of the last line will automatically become the method's return value, even if you do not include the return keyword. This is referred to as implicit returns.
  • Within a class' definition, it's important to understand the scope of any given variable. An instance variable is defined at the class-level, and is accessible through out the entire class (e.g., all of the class' methods and other attributes can access an instance variable). On the other hand, a local variable has a much more limited scope, as it is only accessible within the method in which it is defined. Remember that instance variables are usually created within a class' initialize method, and their names always start with a @ character. Local variables, on the other hand, are defined within a method, and have no special naming convention.
  • To see all instance variables in a particular class, call the object's .inspect method. For example, fido_the_dog.inspect.
  • When you create your own class, it contains both the methods that you explicitly create PLUS some built in methods that Ruby assigns to all classes. For example, all classes have a built in to_s method, even if the class' creator doesn't create it. Keep in mind that you can overwrite any of the built in methods created by Ruby by simply redefining them within your class' definition.
  • When naming Ruby files, use all lowercase letters (e.g., test.rb). Also, if there are multiple words in the file's name, separate the words with an underscore (e.g., bank_account.rb).
  • When writing an if statement, the parenthesis are optional, and it is a standard Ruby convention to omit them. For example:
    # This is good.
    if 1 == 1
      # Do something cool
    end

    # This is less good.
    if(1 == 1)
      # Do something cool
    end
  • To check if a variable is nil, call nil?. For example, dog.nil?.
  • To check if a variable exists, call defined?. For example, if defined?(foo). In this example, the if condition will only be satisfied if the variable foo exists. Note that defined does not return true if the variable exists -- it returns the type of the variable that foo is (e.g., local-variable). To instead return a true or false, you can do the following:
    foo = 'bar'
    puts defined?(foo).nil? # Returns true
  • It is sometimes necessary to assign a value to variable only if that variable does not already have a value. To do so, you can use an if statement, or you can alternatively use the following shorthand: foo ||= "bar". In this example, the variable foo will only be assigned the value bar if foo does not already have a value.
  • To reference code that lives in a separate file, use require "‹filepath›". For example, require "./test.rb".
  • In general, methods that end in ! characters indicate that the method will modify the object it's called on. Ruby calls these "dangerous methods" because they change state that someone else might have a reference to. For example, let's say that a class has an instance variable name. Let's also say that the same class has a method upcase_name!, which changes the instance variable name to be uppercase. In this example, the method's name, by convention, should end in ! because calling this method will change that instance variable, and that change will affect all other objects/places/programmers/etc. that may use the instance variable. Note that the ! is a style/readability convention, not a technical requirement within Ruby.
  • This is obvious, but still worth noting... If you create your own class, and then instantiate that class as an object, you can store that entire object into an array, or into a hash, or even require that object be passed into a custom method that you create. In other words, the classes/objects that you custom create are just as valid/usable as the classes/objects that are built into Ruby, like the string or fixnum class/object.
  • You can use the multiplication operator (*) against strings to repeat them. For example, if you wanted to show the - character 30 times (e.g., to act as a horizontal ruler), you would do the following: puts "-" * 30.
  • Ruby offers the keyword unless to be used in place of, or along side, an if. For example:
    foo = "bar"

    unless foo == "bar"
      puts "not bar" # The string "not bar" will be printed.
    else
      puts "bar"
    end
  • A block in Ruby is very much like a method: it can take some arguments and run code for those arguments.
  • There are two ways to define the starting and ending points of a block. First, you can use the do and end keywords. Second, you can alternatively put the block's code inside of { and } characters. The Ruby convention is to use braces for single-line blocks (i.e., where all of the code within the block will be written on a single line) and to use do and end for multi-line blocks. Below are examples of both:
    # Example using do and end.
    i = 0
    loop do
      i += 1
      puts i # 1, 2, 3 will be printed to the screen.
      break if i == 3
    end

    # Example using braces.
    i = 0
    loop {
      i += 1
      puts i # 1, 2, 3 will be printed to the screen.
      break if i == 3
    }
  • It is important to understand that in the example above the loop method is being called, and it is then being passed a block as an argument. The loop method then acts on that block. This is a good example of the ability in Ruby to pass blocks into methods, and then have those methods execute the code defined with the blocks. This provides you with a lot of flexibility.
  • You can pass arguments into a block using the following syntax: [1, 2, 3].each {|n| puts "Number #{n}"}. In this example, the |n| is a block parameter, and its value in this case is going to be each of the numbers in turn, in the order they are listed inside the array. So for the first iteration of the block the value of n will be 1; then for the second iteration the value will be 2, and then 3.
  • The following is another example of a block, which calls the times method (on a fixnum object) to determine when the block completes. In this example, the times method is being passed a block as an argument.
    # Will print "Hi!" three times.
    i = 3
    i.times { puts "Hi!"}
  • As mentioned above, you can pass blocks into methods that you create. When doing so, you instruct the method to execute the block's code by using the yield keyword within the method's definition. For example:
    def my_method
      puts "First line of my_method."
      yield
      puts "Last line of my_method."
    end

    my_method { puts "I'm defined within a block!" }

    # The code above will print the following:

    # First line of my_method.
    # I'm defined within a block!
    # Last line of my_method.
  • In the example above, note that the method doesn't necessarily accept the block as an argument. Instead, you simply call the method and then define a block. If the method's definition contains a yield keyword then the method will execute the block's code. If the method's definition does not contain a yield keyword, then the block's code will be ignored.
  • Blocks cannot contain the return keyword (if they do, an error will occur). Instead, a block always uses an implicit return (that is, the value generated by the last line in the block is always the return value).
  • When you yield to a block within a method, you can pass back arguments to that block. The block can then leverage those arguments within its execution. For instance, in the example below, the block is outputting variables that are set within the method.
    def say_hi
      puts "What's your first name?"
      first_name = gets.chomp

      puts "What's your last name?"
      last_name = gets.chomp

      yield first_name, last_name # <-- Passed to block
    end

    say_hi do |fname, lname|
      puts "Hi there, " + fname + " " + lname
    end
  • In the example above, it's important to note that the variables defined within the block (fname and lname) are mapped to the variables yielded within the method (first_name and last_name). This appears to work based on the left-to-right ordering of the variables in both the method and the block. In other words, fname maps to first_name solely because they are both the first variable defined in both the method and the block, not based on their names.
  • In the examples above, the block is not passed to the method as a required argument -- it's passed optionally when the method is called. Alternatively, in the method's definition, you can declare the block as a required argument, which must be passed when the method is called. To do so, you declare the argument like any other (in parenthesis), but you add a & character in front of the argument's name. For example:
    def say_hi(greeting, &my_block)
      # To refer to the block, use `my_block`.
    end
  • When you declare the block as an argument in the method's definition, you can use my_block.call instead of yield. You can also pass arguments to the .call method, and those arguments will pass into the block. For example:
    def say_hi(greeting, &my_block)
      puts greeting
      puts "First Name:"
      first_name = gets.chomp

      puts "Last Name:"
      last_name = gets.chomp

      my_block.call(first_name, last_name)
    end

    say_hi("Fancy seeing you here!") do |fname, lname|
      puts "Hi #{fname + " " + lname}!"
    end
  • When reading the Ruby documentation, it's important to understand how Ruby's built-in methods are described, with respect to arguments and blocks that they accept. For example, review the documentation for the integer class' downto method. The documentation explains that downto accepts both a non-block argument (named limit) as well as a block argument (which the documentation refers to as block). For example:
    age = 34

    age.downto(29) { |x| puts x }

    # Will print the following:
    # 34
    # 33
    # 32
    # 31
    # 30
    # 29
  • In the example above, and as explained in the Ruby documentation, if you do not pass a block when calling downto then the method will simply return an enumerator object.
  • From what I can tell, you cannot pass blocks defined within loops to methods as arguments. For example, you could not pass the following into a method: while i < 10 do puts i end.
  • When yielding to a block (within a method's definition), you can pass an argument of self back to the block. This argument is the instance of the class (the class that owns the method). For example:
    class Dog
      attr_accessor :breed

      def initialize
        @breed = "Westie"
      end

      def bark
        puts "Woof!"
        yield self if block_given?
      end
    end

    fido = Dog.new

    fido.bark do |d| # d is the instance of the class
      puts "Bark, bark, bark!"
      puts d.breed
    end
  • The term domain modeling refers to the process of lying out your program's functionality into different modules, classes, methods, and variables. It's the overall object oriented design of your program.
  • It can be handy to write an if statement in the following way:
    do_something if 1 == 1
  • The gsub method (which is a member of Ruby's built-in String class) does a find/replace. For example:
    test = "Fancy 123 Pants"
    puts test.gsub(" 123 ", " ") # Displays "Fancy Pants"
  • You can persist Ruby objects to a .yml file, and then reload them from the file. This is somewhat complicated topic that is not covered in my notes here, but it's important to know that it's possible to do.
  • A module can't have instances, because a module isn't a class. However, you can include a module within a class definition. When this happens, all the module's instance methods are suddenly available as methods in the class as well. They get mixed in. In fact, mixed-in modules effectively behave as superclasses.
  • In the example code below, a module named Animal contains a method named die. This module is then mixed into to the Dog class (via the include keyword). By doing so, all instances of Dog can now call the die method, even though this method isn't defined within the Dog class.
    module Animal
      def die
        puts "Oh no. I'm dead!"
      end
    end

    class Dog
      include Animal
    end

    dog = Dog.new
    dog.die
  • It is a Ruby convention to name modules in the same way that classes are named. That is, they each word starts with a capital letter, via camel-casing.
  • Constants are like variables, but they cannot change (if your program changes a constant, Ruby will throw a warning). You can define a constant in a module or in a class. When doing so, the standard Ruby convention is to name the constant using all upper-case, and to use under-scores in place of spaces (an uppercase first character is what identifies the object as a constant to the Ruby interpreter -- the casing of the other characters in the name aren't relevant to the interpreter). For example, the following module defines two constants.
    module Animal
      VERSION = 1.0
      OWNER = "Jonathan"
    end
  • To access a constant outside of its module or class, use the following syntax:
    module Animal
      VERSION = 1.0
      OWNER = "Jonathan"
    end

    puts Animal::OWNER # Will display "Jonathan"
  • Below are examples of constants defined in both a module and a class.
    module Animal
      OWNER = "Jonathan Powers"
    end

    class Dog
      include Animal
      VERSION = 1.0
    end

    puts Animal::OWNER # Outputs "Jonathan Powers"
    puts Dog::VERSION # Outputs 1.0
  • One important point to understand is that Ruby classes in an of themselves are constants. For example, note how the following class names start with an uppercase character: Array, String, Hash.
  • Modules also act as namespaces. In the code below, the Dog class lives within the Animal module (or namespace). Note how :: characters are used when creating a new instance of Dog -- these are required when a class is stored within a module.
    module Animal
      VERSION = 1.0

      class Dog
        def bark
          puts "Woof!"
        end

        def print_version
          puts VERSION
        end
      end
    end

    dog = Animal::Dog.new
    dog.bark # => Woof!
    dog.print_version # => 1.0
  • In the example above, note that the class definition does NOT have include Animal. When a class lives within a module, there is no need for the include.
  • If you have two classes defined at the same level, in the same namespace, then you don't need to use the :: characters. For example, in the code below, the Cat class creates a new Dog object without using ::.
    module Animal
      class Dog
        def bark
          puts "Woof!"
        end
      end

      class Cat
        def kill_dog(dog_to_kill)
          dog_to_kill = Dog.new
          puts "He dead!"
        end
      end
    end

    dog = Animal::Dog.new
    cat = Animal::Cat.new
    cat.kill_dog(dog) # => He dead!
  • You can create multiple levels of namespaces, by storing modules within modules. When doing so, you have to use multiple :: characters to point to the desired class. For example:
    module Animal
      module FriendlyAnimal
        class Dog
          def bark
            puts "Woof!"
          end
        end
      end

      module MeanAnimal
        class Cat
          def purr
            puts "Meow..."
          end
        end
      end
    end

    dog = Animal::FriendlyAnimal::Dog.new
    dog.bark # => Woof!

    cat = Animal::MeanAnimal::Cat.new
    cat.purr # => Meow...
  • Objects that are built-into Ruby (like String and Array) are part of the Ruby Core, and do not have to be required in order to be used. On the other hand, the Ruby Standard Library is a large collection of internal libraries that ships with every Ruby implementations, which offer additional, commonly-used functionality on top of the Ruby Core. Unlike core objects, standard libraries must be required specifically if needed.
  • The Ruby Standard Library is made up of packages. To see a list of all the available packages, see the sidebar on this page. To use a package, you must require it. For example, to use the CSV package, you would do the following: require "csv".
  • Be aware that Ruby Core has a built-in Math module that provides a lot of mathematical functionality. For example, it provides a constant named PI and a method named sqrt (short for sqaure root).
  • A couple of points about the include statement. First, it has nothing to do with files. The Ruby include statement simply makes a reference to a named module. If that module is in a separate file, you must use require to drag that file in before using include. Second, a Ruby include does not simply copy the module's instance methods into the class. Instead, it makes a reference from the class to the included module. If multiple classes include that module, they'll all point to the same thing.
  • Though this is not a hard and fast rule, in Ruby class names tend to be nouns, whereas module names are often adjectives (e.g., Stack versus Stacklike).
  • It can often be helpful to mixin Ruby Core modules into your own classes. By doing so, you gain all of the module's functionality, without having to write any extra code. A common example of this is mixing in Ruby's Enumerable class, which exposes a lot of very helpful traversal, searching, and sorting methods. For example, let's say that you have a class called DogPound that contains a bunch of Dog objects. And let's also say that each Dog has a name and an age. What if your program needs to find if any Dogs in the DogPound are of a certain age? Sure, you could write your own method to iterate over each Dog object, and find if at least one meets this criteria, and then return a boolean. However, it would be much easier to simply leverage the Enumerable module's built-in any? method, which does all of the heavy lifting for you. See below for an example.
    class DogPound
      include Enumerable
      attr_accessor :dogs

      def initialize
        @dogs = []
      end

      def each(&block)
        dogs.each(&block)
      end

      def add_dog(name, age)
        dog = Dog.new(name: name, age: age)
        dogs.push(dog)
      end

    end

    class Dog

      attr_accessor :name, :age

      def initialize(hash)
        @name = hash[:name]
        @age = hash[:age]
      end

    end

    dog_pound = DogPound.new

    dog_pound.add_dog("Fido", 11)
    dog_pound.add_dog("Mark", 7)

    puts dog_pound.any? { |dog| dog.age > 5 } # => true
    puts dog_pound.any? { |dog| dog.age > 50 } # => false
  • In the example above, it's not obvious why the each method is being created in the DogPound module (since it is never explictly called. If you were to remove this method definition, however, the code above would error out. This appears to be a standard requirement when mixing in the Enumerable module, as explained here
  • It's important to understand the different between include and require in Ruby. The include method takes all the methods from another module and includes them into the current module. This is a language-level thing as opposed to a file-level thing as with require. The include method is the primary way to "extend" classes with other modules (usually referred to as mix-ins). For example, if your class defines the method each, you can include the mixin module Enumerable and it can act as a collection. This can be confusing as the include verb is used very differently in other languages. The require method is used to load another file and execute all its statements. This serves to import all class and method definitions in the file.
  • You can run code whenever a module is included in (i.e., mixed into) a class. In other words, right when the include method is called within the class, your code will run. To do so, within the module's definition you define a method self.included and and pass it a variable that corresponds to the instance of the class that is mixing in the module. For example: self.included(klass). Note that the word klass here is arbitrary, and can be almost anything -- it is simply a name to use when referring to the class instance. It is a Ruby convention to use klass because class is a reserved word in Ruby and cannot be used. The following is an example of a module that is mixed into two classes.
    module Animal
      def self.included(klass)
        puts "I love being included!"
      end
    end

    class Dog
      include Animal
    end

    class Cat
      include Animal
    end

    dog = Dog.new # => I love being included!
    cat = Cat.new # => I love being included!
  • In the example above, note that self.included is a class method.
  • There is a difference between class methods and instance methods. Class methods are methods that are called on a class and instance methods are methods that are called on an instance of a class. Class methods must be named with self. in front, like self.foo. In the example below, a class method is defined (foo), and in order to call it, you must do so directly off of the class, not off an instance of a class. Alternatively, and also included in the code sample below, an instance method is defined (bar), and it can only be called off of a instantiated instance of the class.
    class Test
      def self.foo
        puts "I'm a class method!"
      end

      def bar
        puts "I'm an instance method!"
      end

    end

    Test.foo # => "I'm a class method!"
    Test.new.bar # => "I'm an instance method!"
  • In addition to include, you can also mix a module into a class using extend. However, these two keywords do not provide the exact same functionality, and it can be somewhat abstract to explain their differences. Essentially, include mixes in the module's objects in a way where each INSTANCE of the class can use them. On the other hand, extend mixes in the module's objects in a way where each instance CANNNOT use them -- instead the actual class itself can use them. Another way to word this is, when using include, you are mixing in instance objects. When using extend you are mixing in class objects. Here is an excellent description of these two keywords.
  • A Struct is a convenient way to bundle together attributes and methods without having to build out a whole class. In other words, a Struct allows you to on-the-fly create something that works just like a class, in it that it has attributes and behavior. Below is an example of how to create a Struct.
    SelectOption = Struct.new(:display, :value) do
      def to_ary
        [display, value]
      end
    end

    option_struct = SelectOption.new("Canada (CAD)", :cad)

    puts option_struct.display
    # Canada (CAD)

    puts option_struct.to_ary.inspect
    # ["Canada (CAD)", :cad]
  • In the example above, the to_ary method is an instance method, available to be called on any instance of the struct/class.
  • Also in the example above, option_struct is a full-blown instance of the SelectOption class, even though you never technically created this class. As a result, you can access the instance's variables (display and value) directly, even though you never wrote an initializer method or called attr_accessor. This is one of the major benefits to using a Struct: it's less overhead than creating a full-blown class. That being said, there are other, more beneficial reasons to use a Struct, though most of them seem to require more experience with Ruby than I currently have to appreciate. Here is a great article that covers when to use a Struct.
  • On Ruby class inheritance (source): "In Ruby, a class can only inherit from a single other class. Some other languages support multiple inheritance, a feature that allows classes to inherit features from multiple classes, but Ruby doesn't support this. [...] The benefit of inheritance is that classes lower down the hierarchy get the features of those higher up, but can also add specific features of their own." Below is an example:
    class Mammal
      def breathe
        puts "inhale and exhale"
      end
    end

    class Cat < Mammal # < instructs Cat to inherit from Mammal.
      def speak
        puts "Meow"
      end
    end

    rani = Cat.new
    rani.breathe
    rani.speak
  • To identify if any given class inherits from a parent class, call superclass, which will return the parent class' name. For instance, sticking with the Mammal/Cat example above: puts Cat.superclass # => Mammal. It appears you can only call superclass on the class itself, not on an instantiated instance of the class (e.g., you could not call rani.superclass from the example above).
  • The built-in File class provides functionality to work with files. For example, the code collects some information from the user and then writes it to a file.
    File.open("example.txt", "w") do |file|
      print "Enter your name: "
      name = gets.chomp
      file.puts "Name: #{name}"

      print "Enter your email: "
      email = gets.chomp
      file.puts "Email: #{email}"
    end
  • Ruby offers a built-in way to serialize objects, letting you store them somewhere and reconstitute them when needed. Ruby calls this kind of serialization marshaling, which is available via the Marshal class. You can call Marshal.dump(object) to "dump" any Ruby object into a variable, or into a file. You can call Marshal.load(object) to load a serialized object back into a variable. In the example below, an object is created, dumped to a file, and then later reloaded into a new variable.
    class Dog
      attr_accessor :name

      def initialize(name)
        @name = name
      end
    end

    fido = Dog.new("Fido")

    File.open('fido_file', 'w+') do |f|
      Marshal.dump(fido, f) # The fido object is saved to a file.
    end

    fido_new = false
    File.open('fido_file') do |f|
      fido_new = Marshal.load(f) # The same object is loaded into a new variable.
    end

    puts fido_new.name # => Fido
  • Similar to marshalling, you can also serialize Ruby objects using the JSON class. To dump an object to JSON, call JSON.dump(). To load a Ruby object from JSON, call JSON.load().
  • YAML is often used for configuration files.
  • When calling YAML.load or JSON.load (or any other similar load method), there are security concerns. Essentially, never load data from a source that isn't trustworthy.
  • The Logger class gives you a quick and easy way to generate and write to a log file. In the example below, a log file is created whenever a new instance of Dog is initialized. In addition, the log file is added to whenever an instance of Dog sends out a greeting.
    class Dog
      require "logger"

      attr_accessor :name, :logger

      def initialize(name)
        @name = name
        @logger = Logger.new("#{name}.txt")
      end

      def greet
        puts "Hi, I'm #{name}"
        logger.info("#{name} sent out a greeting. What a friendly puppy!")
      end
    end

    fido = Dog.new("Fido")
    fido.greet
  • In the example above, logger.info is called. In this context, info is one of the levels that Logger supports. The other levels include error and debug, amongst others.
More Posts About... programming / ruby on rails

The Staircase

I finished Netflix's revival of The Staircase and it was excellent. What struck me throughout was how unsentimental, unstylized, and overwhelmingly grounded the series was. It felt less like a long documentary series and more like I was an invisible member of the Peterson family, silently going through the events with them. There's tons of minutiae and detail -- the series isn't afraid to show you long and mostly uncut courtroom scenes or legal strategizing scences, or even just scenes of the family hanging out in silence, anxiously day-dreaming.

After I finished the series I came across The Owl Theory, covered many places on the Internets, including in this Wired article and in the YouTube video below:

Much like Making a Murderer, I don't claim to have an informed opinion on whether the series' subject is innocent or not. I do, however, feel strongly that Peterson is not guilty. And not guilty and innocent are two very different classifications -- a point that I've only recently come to appreciate.

More Posts About... the staircase / tv

Across the Universe

It only took me about 20 years to discover this Fiona Apple music video covering The Beatle's "Across the Universe." It was directed by her then boyfriend P.T. Anderson.



My god those eyes. She's haunting.

More Posts About... fiona apple / paul thomas anderson / music

To Be an Air Traffic Controller

I enjoyed a GQ article from 2009 about the day-to-day life of an air traffic controller. It's a high-stress job that pays poorly, requires overtime, and has really shitty tech.

"These airplanes are headed toward each other on intersecting runways. Too fast. Too soon. Here it comes. The MD-80 is not over the threshold.… Fuck. “Go around!” Cali says into his headset, instructing the RJ to abort its landing. It’s too close to the MD-80. It’s too close… The plane swoops down, then up abruptly, like a gull with a fresh kill." […] "LaGuardia has thousands of go-arounds a year. At an airport like this, everything is a close call, everything is dependent on split-second decisions, snap judgments, jets constantly barreling toward each other. It’s people, just people, with nerves of steel and uncommon courage, keeping the planes from bashing into each other. Just people."

I always assumed the whole operation was mostly automated. It's terrifying to learn how manual and error-prone it all is, plus how unhappy most of the controllers are.

More Posts About... air traffic control

How to Rob

How to Rob is a 1999 song from 50 Cent (that I just discovered). It's apparently what initially put 50 on everyone's radar. 

Aside from being a great track, its approach is interesting: 50 envisions himself robbing the world's biggest hip hop and R&B artists (at the time), one by one. The song's Wikipedia page even lists out each artist that 50 targets (in the order in which they are mentioned):

  • Lil' Kim
  • P Diddy
  • Bobby Brown and Whitney Houston
  • Brian McKnight
  • Keith Sweat
  • Cardan
  • Harlem World
  • Mase
  • Ol' Dirty Bastard
  • Foxy Brown and Kurupt
  • Jay-Z
  • Case
  • Trackmasters
  • Slick Rick
  • Stevie J
  • Big Pun
  • Master P
  • Silkk The Shocker
  • Will Smith and Jada Pinkett Smith
  • Timbaland and Missy Elliott
  • Joe
  • Jermaine Dupri and Da Brat
  • DMX
  • Treach
  • DJ Clue
  • TQ
  • Raekwon, Ghostface Killah and RZA
  • Sticky Fingaz
  • Fredro Starr
  • Canibus
  • Heavy D
  • Juvenile
  • Blackstreet
  • R. Kelly (though not by name, is referenced within the lyrics)
  • Boyz II Men and Michael Bivins
  • Mike Tyson and Robin Givens
  • Mister Cee
  • Busta Rhymes and the Flipmode Squad
  • Kirk Franklin

My favorite two lines turn out to both be fat jokes (which I normally don't condone). On Big Pun:

I'll rob Pun without a gun, snatch his piece then run
This n____ weigh 400 pounds, how he gonna catch me, son?

And on Missy Elliott:

Run up on Timbaland and Missy with the pound
Like, "You, give me the cash; you, put the hot dog down"

The song apparently won 50 both a bunch of admirers and a slew of enemies, which is not surprising. All of the lyrics are on Genius.

More Posts About... 50 cent / music

Just Friends

OMG! A new single from the utterly flawless Hayden James.



One of my more favorite moments in life: The day Hayden James retweeted me.

More Posts About... hayden james / music

HomePod Commercial

It's hard not to love this Spike Jonze-directed advertisement for Apple's new HomePod.



I'm torn on the HomePod. It looks like a beautiful piece of hardware (from the best design shop on the planet) -- but I'm skeptical that Siri can be as helpful as Alexa, especially considering Alexa plugs into the Amazon's rich shopping eco-system.

More Posts About... homepod / commercial / apple

Paul Thomas Anderson Series

I'm not quite half-way through Open Culture's five-part, meticulously crafted series on Paul Thomas Anderson. Part 1 is below, the rest are here. Good stuff.

More Posts About... paul thomas anderson / film

Rubocop Makes Me Happy

Having Rubocop tell me that my Ruby code is stylistically flawless makes me feel very good. No, really.

More Posts About... programming / ruby on rails / rubocop

I'm a Ruby Neb

Below is a good example of someone brand new to Ruby (me!) and someone with Ruby experience (not me!) solving the exact same problem. These two methods have the same goal: accept a string, reverse and return it.

def solution(sentence)

  sentence_as_array = sentence.split(" ").reverse!

  reversed_string = ""
  sentence_as_array.each do |x|

    reversed_string = reversed_string + x + " "

  end

  return reversed_string.chop

end

def better_solution(sentence)

  sentence.split(" ").reverse.join(" ")

end

It's crazy how much more elegant the second method is.

More Posts About... programming / ruby on rails

Christina Tosi

I enjoyed the Chef's Table episode on Christina Tosi and her Momofuku Milk Bar. Her menu is fun to look over, especially Cereal Milk Soft Serve, which is, "Made with milk, cornflakes, brown sugar and a pinch of salt, it tastes just like the milk at the bottom of a bowl of cornflakes!"

More Posts About... christina tosi / food / tv

Reverend Carlton Pearson

Reverend Carlton Pearson was a popular and traditional Evangelical leader; a mentee of Oral Roberts. And then one day, he realized that he no longer believed in hell. He now believed that God saves all, through universal reconciliation.

When my little girl, who'll be nine next month, was an infant, I was watching the evening news. The Hutus and Tutsis were returning from Rwanda to Uganda. And Peter Jennings was doing a piece on it. Now, Majesty was in my lap, my little girl. I'm eating the meal, and I'm watching these little kids with swollen bellies. And it looks like their skin is stretched across their little skeletal remains. Their hair is kind of red from malnutrition. The babies, they've got flies in the corners of their eyes and in their mouths. And they reach for their mother's breast. And the mother's breast looks like a little pencil hanging there. I mean the baby's reaching for the breast. There's no milk. And I, with my little fat-faced baby, and a plate of food, and a big screen television -- and I said, God, I don't know how you could call yourself a loving, sovereign God, and allow these people to suffer this way, and just suck them right into hell, which is what was my assumption. And I heard a voice say within me, so that's what you think we're doing? And I remember I didn't say yes or no. I said, that's what I've been taught. We're sucking them into hell? I said yes. And what would change that? Well, they need to get saved. And how would that happen? Well, somebody needs to preach the gospel to them and get them saved. So if you think that's the only way they're going to get saved is for somebody to preach the gospel to them and that we're sucking them into hell, why don't you put your little baby down, turn your big screen television off, push your plate away, get on the first thing smoking, and go get them saved? And I remember I broke into tears. I was very upset. I remember thinking, God, don't put that guilt on me. I've given you the best 40 years of my life. Besides, I can't save the whole world. I'm doing the best I can. I can't save this whole world. And that's where I remember -- and I believe it was God saying, precisely, you can't save this world. That's what we did.

This realization eventually sent his career into a death spiral.

This American Life covered this story in 2005, but re-ran it again recently in promotion of their upcoming Netflix series "Come Sunday."



I haven't watched the show yet, but the podcast was moving. I found myself rooting for and sympathizing with Pearson. He seems like a genuine and brave man that is following his heart despite the costs.

More Posts About... carlton pearson / podcast / religion

Snippet Bar

I'm constantly re-using the same exact code snippets, for which I never remember the exact syntax. Today I found the free and awesome Snippet Bar, which lives in my macOS menu bar and will prevent me from having to re-look up each code snippet's syntax every time that I need to use it. Win!

More Posts About... macos / app

Dawn Golden

I've been listening to a lot of Dawn Golden lately.



I tend to gravitate (not exclusively) towards music that feels apathetic and effortless. Golden certainly meets that criteria. His music reminds me of Bob Moses.

More Posts About... dawn golden / music

Tools/Apps that I Can't Live Without

Whenever I get a new laptop, I go through the same set up sequence of installing a series of "can't live without" programs and tools -- things that are absolutely essential to my everyday workflow, things that I have trouble functioning without. I figured it would be helpful if I threw all of these into a blog post for everyone to see.

Note that the list below is ultra macOS oritiented (sorry Windows/Linux folks). Also, I left off the really obvious stuff (like Chrome).

  • Tyke: I both can't live without Tyke and can't really explain why it's so damn useful. Tyke bills itself as, "A little bit of scratch paper that lives on your Mac menu bar." I use it almost all day long, every day. I am constantly parking text in Tyke, to either cleanse the text of formatting or just to come back and get it a few seconds/minutes later. To be clear, Tyke is not a place to take notes -- it's a very temporary location to store a small amount of text. Does that make sense? Probably not. But of all the tools listed here, Tyke is likely my favorite.
  • Caffeine: Stop your computer from going to sleep -- ever. There are few things more annoying to me than walking away from my computer for a bit, or even having a conversation in front of my computer (especially during a presentation) and having my computer go to sleep, which now means that I have to log back into it. Caffeine stops all that nonsense, without having to dig into System Preferences. You can enable/disable Caffeine from the menu bar in a single-click.
  • Day-0: About five times a day I need to look at a calendar, just to see what day it is, what dates fall on which days, how many weeks away something is, etc. Day-O lives in my menu bar and gives me answers to these question in a single-click.
  • ShiftIt: Dead simple window manipulation via hotkeys. Easily put two windows side-by-side or on top of each other. Or, quickly maximize a window (without going into the annoying and awkward "full screen" mode on macOS). My skin crawls when I'm using someone else's machine that doesn't have ShiftIt installed.
  • Work at Night: I'm often working in bed at night next to my poor wife who is trying to sleep. In a pitch-black room decreasing my laptop's brightness to zero still isn't dark enough. Work at Night allows you to decrease your brightness even further.
  • Paste 2: An infinite history of everything you've ever sent to your clipboard. This application is both a life-saver (it often saves data that I would have otherwise lost) and a time-saver (when performing repetitive copy/pasting sequences, Paste 2 allows you to move much faster).
  • f.lux: You don't know that you need this application until you try to live without it. f.lux "makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day." When working early in the morning or late at night, f.lux is like a warm blanket and hot cocco -- it just makes you feel better.
  • WeTransfer Moment: This is the only browser extension on my list. Whenever you open a new browser tab, a new full-screen -- and usually awesome -- image is shown. This makes for quite the conversation starter when I'm giving demos and presentations, plus it's just pleasant to look at.
  • Bartender: Because I love to install apps that live in the macOS menu bar (see above), I need a way to easily manage my menu bar. This primarily means hiding Apple's system menu bar items that I don't often use to give me more real-estate. Bartender allows me to do exactly that.
More Posts About... apps / tools / productivity

Deck of Cards API

Deck of Cards API is a series of public and authentication-less endpoints that simulate a deck of cards. Commands include shuffle and draw. I sometimes need a dummy API that I can test against -- this one is definitely more fun than the others I've used.

More Posts About... programming

Effortless

I'm immediately interested in Effortless. I've found that if I don't define a goal before starting to work on something, I lose focus. This simple menu bar-based app seems like it will allow me to easily define a goal, with a time box. I plan to give it a shot this week.

More Posts About... macos / app

Drake Covers

What’s better than a Drake song? An awesomely executed Drake cover from an unexpected source. I’ve come across a many a Drake cover on the YouTubes -- below are my three favorites.

More Posts About... drake / florence and the machine / sampha / music

Notion

Notion is a super interesting tool. I built out a set of pages for my team and am considering rolling it out to them soon. (To my wife's "delight", I also built us a family Notion workspace.)

More Posts About... notion / productivity / app

Progress Bar OSX

Progress Bar OSX is an adorable menu bar app that lives in your toolbar and tells you how much of your day, month, and year you have remaining.



At first glance I thought this was charming and useful. After thinking about it more though, I could see myself forgetting about this app within minutes of installing it. I really want to like it, for some reason.

More Posts About... macos / app

CalorieCalc

I finally found a calorie counting iOS app that I like. It's called CalorieCalc.

It's crazy dead simple, which is what I prefer. Don't give me a giant food database to pull from, don't try to track my exercise, and don't ask me to care about micro-nutrients. Just let me tell you my calorie limit for the day and then allow me to burn down from that limit by manually entering calories for each meal/snack.

I suspect that I'm in the vast minority in wanting such a limited calorie counting app.

More Posts About... diet / ios / app / health

Sleep

I just discovered "Sleep" by Max Richter, an 8 hour and 24 minute album described by the artist as "an eight-hour lullaby...a piece that is meant to be listened to at night." I have trouble mixing sleep with anything but the sound of a fan, but this sounds like excellent music to work to. I plan to give it a shot this week.

You can listen to the album on Amazon and Spotify (amongst other places).

More Posts About... max richter / sleep / music

The National Videos

I have no topical reason for posting three The National videos today -- it's just something that I feel compelled to do. I find myself returning to these videos over and over -- this band is devastating.

Of note: The first video (above) features Sufjan Stevens singing backup. Also related to that same video: I was convinced for a few minutes that Eric Clapton was playing the weird harmonica/piano-hybrid thing.

More Posts About... the national / music

Mt. Gox

Fortune has a solid piece on Mark Karpelès, the former owner of Mt. Gox. If you haven't heard of Mt. Gox, it was once the world's largest bitcoin exchange, which flamed out in epic fashion after mysteriously losing 850,000 of its customer's bitcoins. But wait, the plots thickens.

It wasn't until his lawyers had gone home for the day that Karpelès could retreat to his computer, and that's when he noticed the shocking number on his screen. Following his company's collapse, he'd spent days methodically double-checking Mt. Gox's old digital wallets, where the secret alphanumeric keys for accessing Bitcoins are stored. One after another -- a dozen so far -- the wallets had come up empty. But this time, when the blockchain-scanning program finished running after six hours, it had silently served up an unexpected result: He'd found 200,000 Bitcoins, stashed away in an archived file in the cloud -- apparently forgotten and untouched for three years.

So great, you're thinking: he found 200,000 of the 850,000 missing bitcoins. Yes, but also, by that time the price of a single bitcoin had sky-rocketed. This meant that the 200,000 re-discovered bitcoins were worth ~10x more than lost bitcoins. Now what?

More Posts About... mark karpelès / bitcoin / mt. gox

Best Ever Movie Ending

I've long thought that Lost in Translation had the all-time best ending to any film. That said, I just saw Call Me By Your Name and I may need to change my answer.

Without any context at all, below are both endings. Both are gutting.

More Posts About... lost in translation / call me by your name / film

Naughty Pics Policy

A buddy of mine did some UX work for Hornet, the gay social network. Having no idea that such a network existed, I checked out their website and became immediately fascinated with their documented guidelines around images uploaded to the platform. The specificity here is unreal.

  • A partial nude ass shot (full nude ass shot is a serious violation).
  • Photos that aren't you (celebs, your ex, that guy you hate, your mother-in-law etc). 
  • Genitals covered up by a towel, hat, tea cup, thimble, bed sheet, emoji, your hand, etc.
  • Grabbing/holding or touching genitals or genital area. That includes through your shorts.
  • Erection or outline of genitals through clothing. This is a subjective one. We allow a 'genital bulge'. But, if the outline shows the shape of the penis and testicles, then it will be rejected. This can be affected by how tight the clothing is and/or how big a boy you are. 
  • Sex toys or props. 
  • Pubic hair or the area of the groin where pubic hair normally grows.
  • Photos with underpants visible. 
  • Photos of any obscene gestures and/or lewd behavior. (Flippin' the bird, the finger etc)
  • Illegal drug use or drug paraphernalia (if it looks dodgy, it's a no-no, such as a 'roll-up' cigarette). Also includes drug use in a State or Country where it may be legal. 
  • Depictions of underage drinking (as we aren't Interpol and don't know the legal age for drinking in each country, anyone who looks young will have the photo rejected). 
  • Drawings, painting, cartoons, artwork or overly stylized photographs
  • Image used to advertise services, goods, events, websites or apps (your profile may be suspended for being commercial).
  • Copyrighted or photographer marked images or illustrations
  • No profanity or curse words on a photo. Includes holding up paper with curse words written on it. 
  • Photo of just the crotch: front, side, back, pixelated, clothed, whatever. This would include a photo taken from the waist down. Just because your legs are in it does not mean it isn't a crotch shot. If the main focus is of the crotch, it's not allowed. As a general guide, if your head is not in the photo, then it is more likely to be considered a crotch shot. 
  • Extreme close-up photos, photos where it is unclear what the photo is of. This includes single color photos.
  • Photos with only, or mainly, text. As a general rule, one word or one line of text superimposed on a photo is acceptable (unless the font is large and dominates the photo). 2 or 3 lines of text will likely result in a photo being rejected. 
  • Photos which are gross, disgusting, nasty, yucky, terrible, abhorrent, repugnant. For example, a person vomiting, or a photo of vomit. 

What I would give to be a fly-on-the-wall in the internal meetings that it inevitably took to document these rules.

More Posts About... hornet

This is America

Childish Gambino's new music video This is America is something special, to say the least.



Provocative, disturbing, and dense...while somehow still catchy. Donald Glover continues to surprise me.

More Posts About... donald glover / music

Parkinson's Law

Parkinson's Law claims that:

  • Work expands so as to fill the time available for its completion.
  • If you wait until the last minute, it only takes a minute to do.
  • The demand upon a resource tends to expand to match the supply of the resource (If the price is zero).
  • The amount of time that one has to perform a task is the amount of time it will take to complete the task.

I'm scared to admit that this is very likely true, especially with things that I work on. When I'm sometimes forced to push something out with very little time and under pressure, I'm often surprised (and secretly bummed) that no one notices. Time boxing and forcing mechanisms are probably good things, in many cases.

More Posts About... parkinson's law

UX Psychological Tricks

Nerdwriter covers the psychological tricks of UX design. These include an app that adds a simulated speck of dust to the screen, hoping that you'll click a button in trying to remove the e-dust (that one would definitely work on me). Also interesting is just how difficult it is to close your Amazon account.

More Posts About... ux

Tidy Phone

I did some iPhone house cleaning today, and I'm surprised by how refreshed it makes me feel.

I changed my "lock screen" image:

Best of all, by categorizing all of my apps I forced everything onto a single page.

It's the little things...

More Posts About... iphone

David Foster Wallace Videos

Yesterday I rewatched The End of the Tour for probably the fourth time. It's fast becoming one of my favorite films. Interestingly, I've never read a David Foster Wallace book. Like so many people, I've started and abandoned Infinite Jest numerous times (I also once tried to read The Broom of the System but didn't succeed). Nonetheless I love the idea of DFW. I particularly love listening to him being interviewed, and also hearing other people talk about him. Both are endless interesting to me.

Below are two of my favorite DFW videos. The first is of a New Yorker panel where DFW is the topic. The second is a fascinating interview DFW did with Charlie Rose in the 90s. I have probably watched both of these videos five times each.

More Posts About... david foster wallace

Heaven's Gate Podcast

I quickly surged through the entire Heaven's Gate podcast. I had obviously heard of the group before, but I only knew the big broad strokes. Below are three new things that I learned from the podcast:

  • While Herff Applewhite was the face of the group (and the face that I remember from news coverage), the group's dominant leader/founder was Bonnie Nettles (who died 12 years before the mass suicide). Nettles and Applewhite were known as Ti and Do, respectfully
  • A number of the male members castrated themselves while in the group. From a Rolling Stone article:
    Applewhite and other members underwent the procedure to help ensure they remained celibate. Applewhite, who had been fired as a music professor at the University of St. Thomas in 1970 after administrators learned he had sex with a male student, sought cures for his homosexual urges. He wanted to find a way to have "platonic relationship where he could develop his full potential without sexual entanglements," said one reporter who infiltrated the group in 1975. Castration, Applewhite believed, could make that easier. Ultimately, the group instituted a strict "no sex, no human-level relationships, no socializing" rule.

    Though decisions like this were always left up to the members, eight followers were castrated voluntarily, including Applewhite. "They couldn't stop smiling and giggling," former member DiAngelo told Newsweek. "They were excited about it."
  • While 39 members committed suicide as a group in March 1997, four additional members (who weren't present during the group suicide) killed themself later, on their own.

Below is a trailer for the podcast. I recommend it.

More Posts About... heaven's gate / podcast

Life and Death of Chris Lighty

Today I finished the Mogul: The Life and Death of Chris Lighty podcast. I enjoyed it.

If you're not familiar with Lighty, he was a "500 pound Gorilla"-level manager of major hip hop artists. When I started the podcast, I didn't think I had heard of him, but it didn't take me long to recognise him as A Tribe Called Quest's manager that is a talking head in Michael Rapaport's outstanding documentary Beats, Rhymes & Life: The Travels of A Tribe Called Quest (I vividly remember Lighty from that documentary, because he used the term "esoteric" in his interview in referring to Q-Tip, and I remember that was the first time I had heard that word used before). Lighty's was a true rags-to-riches story, which ends in a tragic suicide.

Aside from being a well-produced, thoughtful deep dive into an interesting subject, I was struck throughout the podcast by how wonderful it is that someone would take the time to tell this story. Lighty isn't a big enough name to carry a film documentary, and that's where the podcast medium really shines. It allows you to do deep dives into subjects that have (seemingly) small audiences, but using a richer medium than long-form written journalism.

Below is a trailer of the podcast.

More Posts About... chris lighty / hip hop / podcast / music