💾 Archived View for lunacb.house › blog › 2022-11-05.gmi captured on 2024-03-21 at 15:08:08. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

Ruby being a good language

created: 2022-11-05 15:21:04 UTC

modified: 2022-11-05 15:21:04 UTC

Today I had a sudden burst of motivation to do some code-golfing on my local filesystem in Ruby. I'm a bit rusty but I picked it up again pretty quickly. Ruby has a rich set of features designed for iterating over Things in general, and a standard library to support it (a). I don't know how much of my enjoyment of this is a lack of functional programming knowledge, but the tools provided by Ruby are expressive enough to make small but complex operations on Lists of Things effortless to write and read, sometimes to the extent of written in it code being self-documenting in places where they wouldn't be in other languages.

(a) Enumerable class in Ruby

I maintain a daily log of progress on projects that I'm working on, including the amount of time spent on them each day, just for fun. The program I wrote in Ruby prints the total time spent on a project by reading the daily time logged in each diary entry for that project. Here's the program:

#!/usr/bin/env ruby

where = "/home/luna/docs/studywiki/diary/"
project = /= PROJECT: chess/
h=0
m=0

Dir.children(where).select { |p| not File.directory?(where+p) and File.open(where+p).any? { |f| f.each_line.any? { |line| line =~ project } } }.each do |p|
  File.open(where+p) { |f| f.each_line { |s| if s =~ /^TIME:s*([0-9]+)hs*([0-9]+)m/ then h += $1.to_i; m += $2.to_i end } }
end
puts "#{h+(m/60).to_i}h #{m%60}m"

as long as you can actually read Ruby, this program reads out very similarly to a description of it in plain English; Take the *children* of the directory, *select* only the ones which are *not* *directories* *and* that, when *opened,* contain *any* *lines* matching the *project* header. With *each* of these selected files, *open* them and test *each line* against the TIME: pattern, and if matching, increment the hour and minute counter accordingly.

It just flows. Wheee!!