Jesus Climent: MusicBrainz
Decklin Foster: Why not writing an abstraction of a MusicBrainz plugin for jack and we can use it also in abcde?
I'm not doing any skipping, and crossfade is set to '0'. I continue to use my happy NIH pseudosolution.new song detected (Leonard Cohen - Hey, That's No Way to Say Goodbye) skipping detected, not submitting.
STDIN.to_a.sort_by rand .each l puts lAs Philipp warns, however: "Ruby is full of fun and power; one must watch out that the scripts remain readable". For a fairly toy example, this solution is still fairly readable, however I can see hair growing on this thing if your program grows large. Next, Pierre-Charles David showed his qualifications for becoming a co-author of the next edition of the Pickaxe (AKA "Programming Ruby: The Pragmatic Programmers' Guide"), with his example and explanation. He's kindly given permission for me to reproduce his e-mail in it's entireity, since it's too good to chop up:
Here is the shortest and most readable version of your "randomize stdin" script I can think of:Pierre, your explanation definitely helped, and I hope it helps others too. The third person to help me out is Decklin Foster, through a post in his blog. What particularly caught me about his solution was the neat demonstration of another feature of Ruby which I think I will really learn to love: the ability to dynamically add methods to an existing class. "Aiee!" I hear all the purists scream -- and I can see the potential for severe misuse, too. But, since every good idea seems to get deeply perverted, we may as well have some real useful features to pervert while we're at it. Decklin has the clever idea of adding methods to the Array class that shuffle the elements of the array in a random fashion. His code is beautiful in it's simplicity:#!/usr/bin/env ruby print ARGF.readlines.sort_by randARGF is a special variable representing either stdin or, in the case where file names are passed on the command line, the content of these files (think of Perl's <>). ARGF behaves like an IO object (although I think it is not one). In particular, it responds to the #readlines method which splits the receiver's content into lines and returns an array. In other words,lines = ARGF.readlinesis the idiomatic way of doinglines = [] while line = gets() do lines << line endin your example. The next part (sort_by) uses a new form of the sort method, which I think is not documented in the Pickaxe. It implements the Schwartzian transform technique. In essence, a random number is associated to each element of the array, which are then sorted based on this index. As a general style remark, note that although Ruby supports "while" and "for x in y" loops, they are rarely used, in favor of iterators and/or higher order methods. For example, to gather all the input lines in an array without using readlines, one might writelines = Array.new ARGF.each_line l lines << lorlines = ARGF.inject([]) lines, l lines << lHope it helps, and welcome to Ruby!
class Array
def swap!(a, b)
self[a], self[b] = self[b], self[a]
self
end
def shuffle!
each_index do i
j = i + rand(length - i)
swap!(i, j)
end
self
end
end
He then goes on to rewrite my bumbling example in probably the most
comprehensible manner I've yet seen:
STDIN.readlines.shuffle!.each line puts lineDecklin writes, "Now that is cool.". I couldn't have put it better myself. My thanks to Philipp, Pierre-Charles, and Decklin, for helping me along the Ruby path. So, two new Ruby Rules for me to live by:
Next.