citizen428.blog()

Try to learn something about everything

Information Overload 2011-04-10

Motivating MethodFinder Feedback

Apparently there was a certain demand for MethodFinder and after being mentioned on Ruby5, it now has almost 150 followers on GitHub as well as over 200 downloads on Rubygems, which is more than I ever expected. There’s also been some very nice feedback on Twitter:

MethodFinder, where have you been all my life?

[…] that MethodFinder is quite awesome though I’m not sure I’ve ever needed one

MethodFinder is one of the coolest things about Squeak. Neat to see it’s been ported to Ruby

MethodFinder in ruby has to be the coolest Gem I’ve ever seen

geniale

I loved Smalltalk’s method finder. Now there is one for Ruby. Cool!

This is one neat piece of code

Hulk WANTS for #clojure.

Holy shitballs, I need to learn SmallTalk

This is great for Ruby newbies like me !

#Ruby method finder ftw!

Really amazing!!

That’s quite motivating and I’m currently experimenting with some ideas that might eventually lead to another tool useful for Ruby learners.

Information Overload 2011-04-03

Cloud Link Collection

In late 2009 and early 2010 I worked on a very interesting cloud computing project. In the process I accrued a fairly comprehensive link list on the topic, which I already briefly mentioned here. The list was also published on the blog of my back then employer, but since the company doesn’t exist anymore and their site is offline, I figured I might as well put it up here. The gist where I originally collected this is still on GitHub, feel free to fork, add etc.

Cloud Providers

General / Architecture

Getting Started

Security

Programming / Libraries

MapReduce

Blogs

Monitoring

Images

Information Overload 2011-03-27

Information Overload 2011-03-20

Information Overload 2011-03-13

Unsavory 1.0.0 and Methodfinder 1.0.1

unsavory has reached maturity (meaning I can’t really come up with any more stuff I want to add), so i decided it’s enough with the conservative versioning and jumped from 0.3.3 to 1.0.0 :-) Right before Christmas I had changed it from Delicious to Pinboard and today I replaced the previous - rather verbose - output with a nice little progressbar and a log file.

I also did a mini update to methodfinder, which now uses StringIO objects instead of /dev/null for output redirection, which should make the Windows users out there happy.

Haskell Like “Zip_with” for Ruby

I always liked Haskell’s zipWith and sometimes miss it in Ruby, so I wrote my own a couple of weeks ago. I also submitted a pull request to Facets, but since it’s still not included I decided to post the code here in case it’s useful for anyone:

1
2
3
4
5
6
7
8
9
10
def zip_with(other, op=nil)
  return [] if self.empty? || other.empty?
  clipped = self[0..other.length-1]
  zipped = clipped.zip(other)
  if op
    zipped.map { |a, b| a.send(op, b) }
  else
    zipped.map { |a, b| yield(a,b) }
  end
end

Usage examples:

1
2
[1,2,3].zip_with([6,5,4], :+) #=> [7, 7, 7]
[1,2,3].zip_with([6,5,4]) { |a,b| 3*a+2*b } #=> [15, 16, 17]

Smalltalk’s Method Finder in Ruby

Update: The code is on Github now - https://github.com/citizen428/MethodFinder

I changed the argument order (so you don’t have to always specify empty arrays), added support for blocks, do some method filtering based on arity and ensure that the streams get properly restored. I left the original code in this post for reference though.

I always was quite fond of Squeak’s Method Finder, which let’s you enter a receiver, arguments and the desired result and will show you all methods that will return this result when sent to the receiver with the provided arguments. Since I started mentoring courses at RubyLearning 2 years ago I often thought that something like this might be nice for the students of our core course.

Last night I was about to start looking for an implementation of Method Finder in Ruby I found some years ago, but then decided to just write my own, which is more fun and doesn’t take long. Here we go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MethodFinder
  def self.find(obj, args, res)
    redirect_streams

    found = obj.methods.select do |m|
      o = obj.is_a?(Numeric) ? obj : obj.dup
      (o.send(m, *args) rescue nil) == res
    end

    restore_streams
    found
  end

  def self.redirect_streams
    @orig_stdout = $stdout
    @orig_stderr = $stderr
    $stdout = File.new('/dev/null', 'w')
    $stderr = File.new('/dev/null', 'w')
  end

  def self.restore_streams
    $stdout = @orig_stdout
    $stderr = @orig_stderr
  end

  private_class_method :redirect_streams, :restore_streams
end

Here’s how you use it:

1
2
3
4
5
6
7
8
9
10
>> MethodFinder.find(16,5,[3,1])
=> ["divmod"]
>> MethodFinder.find("abc",[/./],%w(a b c))
=> ["scan"]
>> MethodFinder.find("aBc",[],"AbC")
=> ["swapcase!", "swapcase"]
>> MethodFinder.find(10,2,100)
=> ["**"]
>> MethodFinder.find([1,nil,3,4,nil,6],[],[1,3,4,6])
=> ["compact", "compact!"]

I think I’ll pack this up as a gem for our course participants to install and use in their IRBs, but before that I might add/change a couple of things:

  • Exclude method’s based on arity to reduce the number of message sends. Done.
  • Add support for blocks which is trivial. Done.
  • Maybe switch the order of arguments and expected result, so you don’t always have to specify an empty array for the arguments. I am a bit torn on this one though, since I like having the argument list explicit. Done.
  • Redirect stdout and stderr to a StringIO object instead of /dev/null unless someone tells me that the latter works on Windows. Done.
  • Maybe add some sort of method blacklist so they won’t get tried in the block. Done.

This shouldn’t take long, but still may have to wait for a couple of weeks because of a trip I’m taking.