Paludis represents an ebuild’s homepage as a dependency-style heirarchy, since PMS allows use-conditional blocks like:

HOMEPAGE="http://example.org/foo gtk? ( http://example.org/foo-gtk )"

Given this, we want a quick way of extracting the URLs using the Ruby bindings. One could of course use a function:

def extract_homepage_recursively (spec) case spec when AllDepSpec , ConditionalDepSpec spec.each { | child | extract_homepage_recursively(child) } when SimpleURIDepSpec puts spec end end extract_homepage_recursively(id.homepage_key.value) if id.homepage_key

But that’s rather crude. It would be much nicer to use a lambda, since we don’t need a new name for something we’re only using once.

Unfortunately, recursive lambdas are sometimes rather pesky. There are various solutions, most of which involve passing the lambda as a parameter to itself. In the general case, there’s the infamous Y combinator, but since Ruby has language-level recognition for recursion there’s no need to resort to that kind of silliness. We could just use a variable:

recurse = lambda do | recurse , spec | case spec when AllDepSpec , ConditionalDepSpec spec.each { | child | recurse.call(recurse, child) } when SimpleURIDepSpec puts spec end end recurse.call(recurse, id.homepage_key.value) if id.homepage_key

But that’s still a pointless waste of a name. We can do better than that.

Ruby 1.9 adds an Object#tap method, which is rather nifty. Ruby 1.8 doesn’t have it, but we can provide it easily:

if not Object .respond_to? :tap class Object def tap yield self self end end end

Then, we don’t need a variable or a horrid untyped lambda calculus construct at all:

lambda do | recurse , spec | case spec when AllDepSpec , ConditionalDepSpec spec.each { | child | recurse.call(recurse, child) } when SimpleURIDepSpec puts spec end end .tap { | r | r.call(r, id.homepage_key.value) } if id.homepage_key