citizen428.blog()

Try to learn something about everything

Shenanigans

About 1.5 month ago I finally packaged some of my Ruby extension methods into the aptly named Shenanigans gem. It’s similar to Facets or ActiveSupport, but probably less useful to most people. Also some of the methods actually are in Facets, although sometimes with different names or slightly different semantics. Anyway, since some people told me they actually do like the gem, here’s a quick summary of what the different methods do and how they can be useful.

  • Array#^: Ruby defines Set#^, which returns the elements exclusive between the set and a given enum. Since a lot of people use arrays instead of proper sets in Ruby, I found it makes a nice addition to Array#| and Array#&.

  • Array#random_subarray: Generates one or more random subarrays of an array, using the fact that Ruby can index integers to get the bit values to ensure fast uniform distributions. Similar to Array#sample, but can generate several subarrays at once.

  • Array#zip_with: The more general form of zip (e.g. in Haskell you could define zip = zipWith (,)). Like Ruby’s Enumerable#inject it can take a symbol argument or a block, and like Haskell’s zip it discards excess array elements if one list is shorter than the other, whereas Ruby’s Array#zip only does that if the receiver is shorter than the argument (it adds nils in the other case).

  • Hash#has_shape?: A quick way to check if a hash’s keys are of certain classes. This does feel a bit strange in a duck-typed language like Ruby, but someone asked for it on StackOverflow and it was easy enough to write. This could be useful in validations or unit tests though.

  • Hash#to_ostruct: I really like the rails_config gem. I therefore decided to write something that gives me similar functionality (although a lot simpler) for plain Ruby projects. Basically this recursively converts a hash and all nested hashes into OpenStruct instances. Populate the hash with Ruby’s YAML support and you have an instant settings object.

  • Kernel#fn: I admit, this was more of a “because I can” method. Originally I wrote this so I could compose blocks in pointfree style, but later added support for Proc instances too.

  • Kernel#prompt: While it’s great that Ruby’s IO#gets is so general, I always wanted something like Python’s raw_input for command line apps. Additionally you can also automatically call any of the numeric conversions, and I’m pondering adding support for every unary string method.

  • Kernel#with: I think Object#tap is great. However, I sometimes see it used as a replacement for Enumerable#inject or Enumerable#each_with_object, but for some reason I never really liked the semantics of it. And since I’m anal about that sort of thing I added this Pascal/ActionScript like with statement.

  • Object#display: Having no proper object-oriented way to print objects in Ruby always kinda bothered me, so I abused Object#tap as a wrapper around Kernel#puts and Kernel#print. Additionally this is aliased to the name d, which I stole from irbtools. The latter form makes it great for debugging method chains and the likes.

  • Object#it: I always disliked blocks of the form { |x| x } that sometimes crop up when using Enumerable#group_by or similar methods. Since Ruby lacks an identity method and id has historically been taken, I decided to name it it.

Comments