Dropbox as iPhoto Library Backup

The renewal on my Mozy backup, and I decided that I wanted to consolidate backup solutions. Dropbox had (recently?) upped their paid plan to 1TB, so there was plenty of room to back up a 100GB iPhoto library.

I made the switch on Wednesday of this week, dragging the iPhoto library in Photos over to the Dropbox folder (do this with iPhoto closed and then double-click once moved to let iPhoto figure out the new location.) I did a selective sync to another computer that was lacking in hard drive space so that the Dropbox sync wouldn’t eat up all the space.

Finder claims there are about 98,000 in the library. Dropbox was indexing about 360,000. I haven’t dug into the discrepancy, but I’m guessing hidden files aren’t in the Finder count.

I’ve also done a disk clone of the of the 1TB and gotten caught up on Time Machine backups, but three days later, Dropbox has indexed half of the files and uploaded 10GB of data.

devise_security_extension undefined method authenticate for nil:NilClass on Rspec Tests for Controller That Skips Authentication

After installing the Devise Security Extension to add password expiration to my Devise models, I started getting the following error on an RSpec test for a controller that does not perform authentication of the user:

     Failure/Error: get :index
     NoMethodError:
       undefined method `authenticate?' for nil:NilClass

After a bit of digging, I found that the helpers.rb in the gem includes an additional before_filter that needs to be skipped:

module DeviseSecurityExtension
  module Controllers
    module Helpers
      extend ActiveSupport::Concern
 
      included do
        before_filter :handle_password_change
      end

So while I’m skipping authenticate_user! in my controller, I still needed an additional:

  skip_before_filter :handle_password_change

Interestingly enough, the controller itself doesn’t break, just the tests. The downside is that I’m referencing two different Devise filters/actions just to not use them.

How safe is an MD5 hash of a plain password?

First of all, I hope that you’ve moved beyond MD5 hashes and hashing passwords by themselves, adding salts, etc., but I do recall systems in which an MD5 hash of a password by itself was “good enough”.

You can look up some md5 hashes on this md5 cracker page. I found many two word combinations that were crackable.

You can play with generating md5 hashes of questionable passwords (such as your name and p@ssw0rd) with this md5 Hash Generator

Ruby Keyword Argument Implementation Differences Between 2.1 and 2.2

I’m currently reading through Ruby Under a Microscope: An Illustrated Guide to Ruby Internals, and when I tried to test the “hidden hash” in ruby 2.2, I got different results from the book.

In Ruby 2.2, it appears that the default arguments are used as one expects, without regard to the Hash monkey patch:

### CODE ###
class Hash
  def key?(val)
    false
  end
end
 
def blah(a: 2, b: 5)
  puts a + b
end
blah
blah(a:3)
blah(b:3)
blah(a:2000, b:2000)
 
### DISASSEMBLY ###
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putspecialobject 3
0004 putnil
0005 defineclass      :Hash, <class:Hash>, 0
0009 pop
0010 trace            1                                               (   7)
0012 putspecialobject 1
0014 putspecialobject 2
0016 putobject        :blah
0018 putiseq          blah
0020 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0022 pop
0023 trace            1                                               (  10)
0025 putself
0026 opt_send_without_block <callinfo!mid:blah, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0028 pop
0029 trace            1                                               (  11)
0031 putself
0032 putobject        3
0034 opt_send_without_block <callinfo!mid:blah, argc:1, kw:1, FCALL>
0036 pop
0037 trace            1                                               (  12)
0039 putself
0040 putobject        3
0042 opt_send_without_block <callinfo!mid:blah, argc:1, kw:1, FCALL>
0044 pop
0045 trace            1                                               (  13)
0047 putself
0048 putobject        2000
0050 putobject        2000
0052 opt_send_without_block <callinfo!mid:blah, argc:2, kw:2, FCALL>
0054 leave
== disasm: <RubyVM::InstructionSequence:<class:Hash>@<compiled>>========
0000 trace            2                                               (   1)
0002 trace            1                                               (   2)
0004 putspecialobject 1
0006 putspecialobject 2
0008 putobject        :key?
0010 putiseq          key?
0012 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0014 trace            4                                               (   5)
0016 leave                                                            (   2)
== disasm: <RubyVM::InstructionSequence:key?@<compiled>>================
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] val<Arg>
0000 trace            8                                               (   2)
0002 trace            1                                               (   3)
0004 putobject        false
0006 trace            16                                              (   4)
0008 leave                                                            (   3)
== disasm: <RubyVM::InstructionSequence:blah@<compiled>>================
local table (size: 4, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: 2@0, kwrest: -1])
[ 4] a          [ 3] b          [ 2] ?
0000 trace            8                                               (   7)
0002 trace            1                                               (   8)
0004 putself
0005 getlocal_OP__WC__0 4
0007 getlocal_OP__WC__0 3
0009 opt_plus         <callinfo!mid:+, argc:1, ARGS_SIMPLE>
0011 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0013 trace            16                                              (   9)
0015 leave                                                            (   8)
 
### RESULTS ###
7
8
5
4000

If I reset back to ruby 2.1, I get the unconditional usage of the default arguments:

### CODE ###
class Hash
  def key?(val)
    false
  end
end
 
def blah(a: 2, b: 5)
  puts a + b
end
blah
blah(a:3)
blah(b:3)
blah(a:2000, b:2000)
 
### DISASSEMBLY ###
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putspecialobject 3
0004 putnil
0005 defineclass      :Hash, <class:Hash>, 0
0009 pop
0010 trace            1                                               (   7)
0012 putspecialobject 1
0014 putspecialobject 2
0016 putobject        :blah
0018 putiseq          blah
0020 opt_send_simple  <callinfo!mid:core#define_method, argc:3, ARGS_SKIP>
0022 pop
0023 trace            1                                               (  10)
0025 putself
0026 opt_send_simple  <callinfo!mid:blah, argc:0, FCALL|VCALL|ARGS_SKIP>
0028 pop
0029 trace            1                                               (  11)
0031 putself
0032 putspecialobject 1
0034 putobject        [:a, 3]
0036 opt_send_simple  <callinfo!mid:core#hash_from_ary, argc:1, ARGS_SKIP>
0038 opt_send_simple  <callinfo!mid:blah, argc:1, FCALL|ARGS_SKIP>
0040 pop
0041 trace            1                                               (  12)
0043 putself
0044 putspecialobject 1
0046 putobject        [:b, 3]
0048 opt_send_simple  <callinfo!mid:core#hash_from_ary, argc:1, ARGS_SKIP>
0050 opt_send_simple  <callinfo!mid:blah, argc:1, FCALL|ARGS_SKIP>
0052 pop
0053 trace            1                                               (  13)
0055 putself
0056 putspecialobject 1
0058 putobject        [:a, 2000, :b, 2000]
0060 opt_send_simple  <callinfo!mid:core#hash_from_ary, argc:1, ARGS_SKIP>
0062 opt_send_simple  <callinfo!mid:blah, argc:1, FCALL|ARGS_SKIP>
0064 leave
== disasm: <RubyVM::InstructionSequence:<class:Hash>@<compiled>>========
0000 trace            2                                               (   1)
0002 trace            1                                               (   2)
0004 putspecialobject 1
0006 putspecialobject 2
0008 putobject        :key?
0010 putiseq          key?
0012 opt_send_simple  <callinfo!mid:core#define_method, argc:3, ARGS_SKIP>
0014 trace            4                                               (   5)
0016 leave                                                            (   2)
== disasm: <RubyVM::InstructionSequence:key?@<compiled>>================
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, keyword: 0@3] s1)
[ 2] val<Arg>
0000 trace            8                                               (   2)
0002 trace            1                                               (   3)
0004 putobject        false
0006 trace            16                                              (   4)
0008 leave                                                            (   3)
== disasm: <RubyVM::InstructionSequence:blah@<compiled>>================
local table (size: 4, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, keyword: 2@2] s0)
[ 4] a          [ 3] b          [ 2] ?
0000 getlocal_OP__WC__0 2                                             (   7)
0002 dup
0003 putobject        :a
0005 opt_send_simple  <callinfo!mid:key?, argc:1, ARGS_SKIP>
0007 branchunless     18
0009 dup
0010 putobject        :a
0012 opt_send_simple  <callinfo!mid:delete, argc:1, ARGS_SKIP>
0014 setlocal_OP__WC__0 4
0016 jump             22
0018 putobject        2
0020 setlocal_OP__WC__0 4
0022 dup
0023 putobject        :b
0025 opt_send_simple  <callinfo!mid:key?, argc:1, ARGS_SKIP>
0027 branchunless     38
0029 dup
0030 putobject        :b
0032 opt_send_simple  <callinfo!mid:delete, argc:1, ARGS_SKIP>
0034 setlocal_OP__WC__0 3
0036 jump             42
0038 putobject        5
0040 setlocal_OP__WC__0 3
0042 pop
0043 trace            8
0045 trace            1                                               (   8)
0047 putself
0048 getlocal_OP__WC__0 4
0050 getlocal_OP__WC__0 3
0052 opt_plus         <callinfo!mid:+, argc:1, ARGS_SKIP>
0054 opt_send_simple  <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>
0056 trace            16                                              (   9)
0058 leave                                                            (   8)
 
### RESULTS ###
7
7
7
7

Rails AntiPatterns Review/Summary

I’ve had the Rails AntiPatterns: Best Practice Ruby on Rails Refactoring (Addison-Wesley Professional Ruby Series) book on my Safari Books Online bookshelf for almost a year now, and finally started reading through it. It was “updated for Rails 3″, and there doesn’t appear to be a newer version, so I was a bit skeptical about how much I’d get out of the book.

This book has some overlap with Ruby Science, but it is more Rails-centric in its approach. Going through the book I found quite a few topics that I’ve not really read in-depth on in any other book or come across in a couple years of Rails development experience.

  • Use of ActiveSupport::Concern included for specifying validations as part of a module.
  • Discussion of Rails plugins (which later were mentioned as falling out of favor)
  • serialize :value, Hash vs checkbox/boolean model
  • How Rails helps in the building of Semantic HTML
  • Gems Clearance and AuthLogic as simple authentication gems.
  • MVP pattern and ActivePresenter (looks like Rails 3 was the end?)
  • Emphasis on controller as a representation of a resource
  • Rails responders for changing respond_to to respond_with(object)
  • rescue *EXPECTED_EXCEPTIONS (EXPECTED_EXPECTIONS as a constant array) to whitelist exceptions that are anticipated.
  • Mechanize and RestClient as automated interface gems with other sites.
  • render :status => :unprocessable_entity (or :created and other symbols that represent HTTP status codes)
  • Strategies for testing rake tasks, including FileUtils::NoWrite
  • sqlite3 “:memory:” database for gem testing
  • Thoughts on when to add DB indexes
  • AR association methods count vs. length vs. size and their behavior and resource usage.
  • .flatten() as a code smell for ruby code that should be represented as SQL.
  • Run rake db:migrate && rake db:migrate:redo for all migrations created.
  • Don’t go against AR bias against DB constraints except for NULL & default values.
  • Never fail quietly, whether ignoring return values or overzealously catching all exceptions.
  • rescue_from on controller to redirect specific exceptions.

I think the general concepts covered provided valuable background and food for thought even if not all the solutions are still the same. I don’t regret the help examining current practices in my daily Rails development.

Introducing Elixir

I read through Introducing Elixir on Safari Books Online because I had read through a beta edition of Programming Elixir: Functional |> Concurrent |> Pragmatic |> Fun through The Pragmatic Bookshelf and wanted to see about getting a slightly different take on Elixir at the same time I was getting caught up with the current state of Elixir.

The Introducing Elixir book read to me like a quick tour of Elixir, despite being about 80% of the length of Programming Elixir. That’s probably because I took some time to work through the examples in Programming Elixir, back when Elixir was on its 0.12 release. Programming Elixir is set up to be much more of a textbook in its presentation, with programming problems posed, etc. Introducing Elixir hits upon functional programming, the underlying Erlang and OTP libraries, and throws a few ideas of what you can do with it. It’s a decent refresher to shake the cobwebs out, but it doesn’t as much in depth probing into the language as the Programming Elixir book does. I’d recommend the Programming Elixir book from pragprog.com first.

(Amazon affiliate link)

Open Your Github Repo in a Web Browser from the Shell

This assumes that your first remote is a github remote. Put the following in the appropriate bash or zsh initialization script and that you’re on a Mac. You might need to change “open” to whatever will launch a URL in a web browser on a different *nix system.

function gitweb() {
  git remote -v | head -n 1 | awk '{print $2}' | sed 's/.git$//' | sed 's/git@github.com:/https:\/\/github.com\//' | xargs -I {} open {}
}

Programming Style: Language Specific Domains

My Beginner and C Days

The visual presentation of the code has mattered to me, from the first days I wrote C code in Microsoft editor. In those days, it was a Microsoft C 5.0 IDE on either DOS or OS/2.

#include "stdio.h"
main()
{
 
	int rows,columns,ROW, COLUMN;
	scanf("%d %d",&ROW,&COLUMN);
	rows = 0;
	columns = 0;
	while(columns++ < COLUMN)
		printf("\xdb");
	printf("\n");
	rows += 1;
	while(rows++ < (ROW - 2)){
		columns = 0;
		printf("\xdb");
		while(columns++ < (COLUMN - 2)){
			printf(" ");
			}
		printf("\xdb\n");
		}
	columns = 0;
	while(columns++ < COLUMN) {
		printf("\xdb");
		}
 
 
}

Ok, not *that* far back, but I did have strong opinions about C from the early days of my being paid to program in it:

  • TABS, not spaces
  • 3 (in Microsoft land) spaces per tab (eventually switched to 4)
  • always include braces for if clauses
  • generally no parentheses for return values
  • ternary operator GOOD

That made the code look like this (except that tabs are tabs in pre blocks).

 
int compare(const void *a, const void *b)
{
	return(strcmp(*(char **)a, *(char **)b));
}
 
int checkDictionary(char *word)
{
	if(!dictionary)
	{
		loadDictionary("WORD.LST");
	}
	if(bsearch((void *)&word, (void*)dictionary, wordCount, sizeof(char *), compare))
	{
		return 1;
	}
	return 0;
}

But I remember so much variation in coding style preferences, as evidenced by the Indent Style article on Wikipedia. Everyone had their own preferred style, and everyone had their own preference for how much everyone else should adhere to a common style. On one team I worked, they eventually developed code reviews which were nothing more than berating people for not adhering to an arbitrary style guide: an in-house version Hungarian Notation, exactly one return per function, etc.

Java and Perl days

In Java land, my preference for camelCasing was reaffirmed. Working with Perl and Java, I eventually started putting the opening brace on the same line as if statements and function declarations.

if(iAmAChangedProgrammer) {
   hugWithBraces();
}

I think the brace thing was a result of a block that evaluated differently in awk or perl if it didn’t hug the clause. I don’t remember, but from that point on, I was convinced of that way being the only way.

Ruby

Coming into ruby has been interesting. Multiple returns (which never bothered me) are common. Implicit returns are the norm as well. There’s a style guide which, for the most part, experienced rubyists adhere to (even if there are slight variations in practice). I find some disagreement with some of the style recommendations (I think I have found legit use for and over &&, etc…), but I’m happy to fall in line with the style recommendations and help enforce them.

Some of the styles have obvious purpose, but some seem rather arbitrary. Why are guard clauses so accepted in Ruby when C was so scared of them, etc…

Smalltalk

In reading Smalltalk Best Practice Patterns, it all came together.

As part of the style guide near the end of the book, the author talks about using the line-wrapping of the browser window to naturally wrap argument lists instead of taking up vertical space with them. That’s when it dawned on me how much preferences in code styles also come from the languages that influenced the current language.

Ruby’s heritage from Smalltalk means that it carried forward that aversion to deep nesting that performs poorly in small code browser windows (even in Squeak and Pharo, the code windows can get pretty tiny.)

C coders may have come from GOSUB type languages where there truly was only one return (unless an IF clause buried another) and there could be multiple entry points. Multiple entry and exit point aversion came from languages in which you could GOSUB to anywhere before a RETURN statement, and a nested RETURN could be harder to detect than one on the main logic level.

Conclusion

Early language coding styles likely came from specific pain points experienced by a prior guru and then arbitrarily passed along because “We’ve always done it that way.” At some point, tasks and readable code become hindered by following rules that we don’t have a rationale behind.

Community style guides hopefully have the benefit of thousands of years of cumulative experience in challenges and best practices collaborating on equal footing, but that assumes that we’re not just agreeing with our technical elders because that’s the way it’s always been done.

Try to understand the problem domain of coding in a specific language as it relates to coding style. Maybe your coding style thinks its still programming in COBOL or BASIC.

Toy Helicopter Review and Durability Test: Flutterbye Deluxe Fairy

We’ve bought several cheap toy helicopters that have usually met their demise via the breakage of one of the components that rotates at high speed breaking. Air Hogs has been a favorite brand because they are usually cheap and your face on retail shelves. [The charging port on this doll bears the Air Hogs brand, as well.]

[Somewhat related: our big dog doesn’t like any of these flying things and thinks it’s his mission to “kill” them, giving us an extra obstacle to their longevity.]

This fairy doll is the first one we’ve had that doesn’t look like a standard helicopter for us.

When taking off from its base, the doll floats fairly gracefully to the floor. The doll mostly hovers within a foot or two of the surface underneath her. However, you can cup your hands directly below it and it’ll float above your hands briefly instead. I noticed when I did this, the fairy would float steadily to the ceiling and hover and gradually come back down.

The doll will also take off from your hand, but it’s very easy to not be vertical at take-off and/or to present an uneven surface below it, causing to lift off erratically. I recommend letting it take off from the base stand each time.

We’ve had 5-10 crashes with the doll. One thing I noticed with this doll (unlike manually controlled helicopters) is that power is immediately cut to the rotors when a collision happens. This minimizes the high speed damage that the blades and balances endure when you don’t react quickly enough to cut the power on a remote control.

Between the ease of flight, the safety cut-off, and the relatively more durable structure overall, this doll seems like the best value in the under $50 helicopter department for those of us who really don’t know how to successfully fly a toy helicopter, anyway.

Note:
The doll in the video is the Deluxe Light Up Flutterbye Fairy – Rainbow (Amazon affiliate link)

Toy Helicopter Review and Durability Test: Sky Rover Aero Spin

The Sky Rover Aero Spin was a pretty impressive little toy helicopter.

It has a hover mode that stabilizes flight a certain distance off of the ground and a “controller” mode which allows you to try controlling the spin rate of the propellers to fly the helicopter.  A good video demonstration is on the rcgroups forums.

This helicopter has been by far the easiest budget (<$50) helicopter to fly, at $10 at Wal-Mart ($7.51 online now).

Unfortunately, a collision within the first minute of flight broke the ring holding the blades together onto the spin shaft. [See Flutterbye Deluxe Fairy for a “helicopter” from this Christmas that’s still going.]

We played around with Gorilla Glue to try and repair the ring (should have used crazy glue. After the glue was allowed to set, the helicopter was mostly back in flying shape, with the exception of a bit of constant roll due to the imbalance.

We were able to fly the helicopter for another few minutes prior to a collision that snapped the same fragile ring yet again, both in the glued spot and in the spot opposite to it.

Ease of flight is definitely an A+. There’s virtually no thought to it.

Durability is a bit worse that most Air Hogs brands that we’ve had.

To be determined: If there will be any support from the company who manufactured the helicopter.

Gorilla glued one side, it worked until until side broke along with it
Gorilla glued one side, it worked until until side broke along with it