Substrings in Ruby
The other day I was wondering why some really simple Ruby code of mine wasn’t working. The code under test looked something like this:
I figured that my ls -l.split/\n/ trickery wasn’t working. So I fired up irb and tried it manually. It worked fine.
Then I sprinkled a few puts statements throughout. entries was fine, and each entry was perfect, looking something like this:
I couldn’t figure out what was wrong. All I had to do was look at the first character of entry; if it was a ‘d’, then I knew I had a directory. But for some reason, is_directory was always false. I googled, checked the RDocs for the String class, thumbed through the PickAxe, and something I read triggered one of those ah-ha moments.
Rats: My C# brain is still alive and kicking.
To confirm my fears, I fired up irb again:
That’s right, folks: on a string, the bracket syntax – when given only one parameter – will return the ASCII value of the character inside. Not the actual character, as it will in C#.
To correctly grab a one-character substring from a string, you have to supply two parameters:
def find_directories directories = [] entries = `ls -l`.split/\n/ # get long-format directory listing entries.shift # toss away the totals line entries.each do |entry| is_directory = (entry[0] == 'd') # is it a directory? directories << dir if is_directory end directories end
I figured that my ls -l.split/\n/ trickery wasn’t working. So I fired up irb and tried it manually. It worked fine.
Then I sprinkled a few puts statements throughout. entries was fine, and each entry was perfect, looking something like this:
drwx------ 24 jcohen jcohen 816 Aug 19 11:04 Documents
I couldn’t figure out what was wrong. All I had to do was look at the first character of entry; if it was a ‘d’, then I knew I had a directory. But for some reason, is_directory was always false. I googled, checked the RDocs for the String class, thumbed through the PickAxe, and something I read triggered one of those ah-ha moments.
Rats: My C# brain is still alive and kicking.
To confirm my fears, I fired up irb again:
irb> s = "Jeff" => "Jeff" irb> s[0] => 74
That’s right, folks: on a string, the bracket syntax – when given only one parameter – will return the ASCII value of the character inside. Not the actual character, as it will in C#.
To correctly grab a one-character substring from a string, you have to supply two parameters:
irb> s[0,1] => "J"