Working with Ruby by Jan Lelis

Do you know the official Ruby interpreter "goruby"?

##              ##    ##     ##    ##    ##    ####           ###        ##    ##
 ##            ##     ##     ##     ##  ##     ##  ##        ## ##        ##  ##
  ##    ##    ##      #########      ####      ##   ##     #########       ####
   ##  ####  ##       ##     ##       ##       ##  ##      ##     ##        ##
    ####  ####        ##     ##       ##       ####       ##       ##       ##

If you don’t know what to do on whyday, do not play code golf! It is frustrating! And it is addictive! And you don’t create something useful by golfing!

But it is also fun!

And I am not the only one who wants to squeeze code even more. The original Ruby 1.9 interpreter comes with pretty crazy version of itself: a version for code golfing! Just navigate to the Ruby source and make golf. All it does is adding about 100 lines of Ruby meta programming :)

Do not miss Object#method_missing

Let’s take look at the main modification and try to understand it line by line (or scroll down, if you just want to know what it does ;) ).

 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# code from the Ruby soure, golf_prelude.rb, commented

class Object
  # initialize a global hash cache
  @@golf_hash = {}

  # let's begin the madness: our favourite method
  def method_missing m, *a, &b
    # search the cache for the missing method/class combination
    #  or assign it with the best matching constant name
    t = @@golf_hash[ [m,self.class] ] ||= matching_methods(m)[0]

    # if found in the hash and block_given?
    if t && b
      # call the method named by t and pass the arguments
      __send__(t, *a) {|*args|
        # also pass found regexes
        b.binding.eval("proc{|golf_matchdata| $~ = golf_matchdata }").call($~) if $~
        # and execute the block
        b.call(*args)
      }

    # if no block is given
    else
      # call the method named by t or throw method_missing again
      t ? __send__(t, *a, &b) : super
    end
  end


  # here comes the magic
  def matching_methods(s='', m=callable_methods)
    # build a regex which starts with ^ (beginning)
    # take every letter of the method_name
    #   insert "(.*?)" instead, which means: match anything and take the smallest match
    #   and insert the letter itself (but escape regex chars)
    #
    # for example s='matz'
    # => /^(.*?)m(.*?)a(.*?)t(.*?)z/
    #
    r=/^#{s.to_s.gsub(/./){"(.*?)"+Regexp.escape($&)}}/

    # match all available methods for this regex
    #  and sort them by the least matches of the "fill" regex groups
    m.grep(r).sort_by do |i|
      i.to_s.match(r).captures.map(&:size) << i
    end
  end

  # capture not only methods, but also constants
  def self.const_missing c

    # search the cache for the missing constant/class combination
    #  or assign it with the best matching method name
    t = @@golf_hash[ [c,self.class] ] ||= matching_methods(c,constants)[0]

    # return the constant if it exist
    t and return const_get(t)

    # or raise the error
    raise NameError, "uninitialized constant #{c}", caller(1)
  end

  # get the shortest shortcut for a callable method
  def shortest_abbreviation(s='', m=callable_methods)
    # check if s (method_name) is capitalized
    s=s.to_s
    our_case = (?A..?Z)===s[0]

    # check if method_name is callable (and get its index in the callable method array)
    if m.index(s.to_sym)
      # begin with length 1 and try until method_name's size
      1.upto(s.size){|z|
        # try for all combinations of the method_name letters for the current length
        #  combination:  %w[a b c].combination 2 # is [["a","b"],["a","c"],["b","c"]]
        s.scan(/./).combination(z).map{|trial|

        # skip if current combination is capitalized, but out method_name not
        #  (and vice versa)
        next unless ((?A..?Z)===trial[0]) == our_case

        # join the combination and return it if it is the best matching method name
        trial*=''
        return trial if matching_methods(trial,m)[0].to_s==s
      }}

    # method_name not found
    else
      nil
    end
  end

  # get *all* callable methods of an Object
  def callable_methods
    self.class == Object ? methods + private_methods : methods
  end
  
  # ...
end

By “abusing” method_missing and const_missing for Object, it lets you call methods and constants with the shortest name possible (e.g: [[1,2,3]].fle means [[1,2,3]].flatten). To get the shortest name of a method for an object, you can run for example: "an object".shortest_abbreviation :reverse # => 'rv'

List of further small changes

  • do_while(&block) and do_until(block) methods which return 0 as long/until the block is true.
  • String modifications
    • Alias: String#split —> String#/
    • String#to_a is done via String#split('')
    • It adds Array methods to String which operate on each char
  • Enumerator also uses Array methods that do not exist for Enumerator by converting its instance to an Array
  • Alias: puts —> say
  • Array#to_s via Array#join
  • FalseClass#to_s is '' (instead of false)
  • Integer includes Enumerable via times
  • The most important method h, which [try it out] ;)

GoRuby

Navigate to your Ruby 1.9 source and run make golf

To see goruby in action, checkout shinhs golf server and inspect a problem that is labeled with “post mortem”!

Creative Commons License

Comments

hello there and thanks on your inomifatron ? I have certainly picked up something new from right here. I did then again expertise a few technical points using this web site, as I skilled to reload the site lots of times prior to I could get it to load properly. I have been brooding about if your web hosting is OK? Not that I'm complaining, but sluggish loading instances instances will very frequently affect your placement in google and could harm your high-quality score if ads and marketing with Adwords. Well I'm including this RSS to my email and could look out for a lot extra of your respective intriguing content. Make sure you update this once more soon.. | July 01, 2015

hello there and thanks on your inomifatron ? I have certainly picked up something new from right here. I did then again expertise a few technical points using this web site, as I skilled to reload the site lots of times prior to I could get it to load properly. I have been brooding about if your web hosting is OK? Not that I'm complaining, but sluggish loading instances instances will very frequently affect your placement in google and could harm your high-quality score if ads and marketing with Adwords. Well I'm including this RSS to my email and could look out for a lot extra of your respective intriguing content. Make sure you update this once more soon..

Awesome! I did not know about /u. I have been trying (unsuccessfully) to get ctype_alpha to work with <a href="http://qmwojr.com">aceetncd</a> characters. You learn something new every day A little typo, however. preg_match($pattern, $string, $matches); should be preg_match($pattern, $input, $matches); And that greater than sign is getting htmlentiti-fied. | July 02, 2015

Awesome! I did not know about /u. I have been trying (unsuccessfully) to get ctype_alpha to work with <a href="http://qmwojr.com">aceetncd</a> characters. You learn something new every day A little typo, however. preg_match($pattern, $string, $matches); should be preg_match($pattern, $input, $matches); And that greater than sign is getting htmlentiti-fied.

This makes evthieryng so completely painless. http://zkecxg.com [url=http://kapmfzjg.com]kapmfzjg[/url] [link=http://sstyuwlzgwj.com]sstyuwlzgwj[/link] | July 02, 2015

This makes evthieryng so completely painless. http://zkecxg.com [url=http://kapmfzjg.com]kapmfzjg[/url] [link=http://sstyuwlzgwj.com]sstyuwlzgwj[/link]

bioinformatics is very nice subject but in india there is not <a href="http://kzwuuxldt.com">oprnttueipy</a>..if you have completed your msc or phd in bioinforamtics or life science then you can join in this field but main thing u should have a good refernce. | July 04, 2015

bioinformatics is very nice subject but in india there is not <a href="http://kzwuuxldt.com">oprnttueipy</a>..if you have completed your msc or phd in bioinforamtics or life science then you can join in this field but main thing u should have a good refernce.

Yeah, Precedings, Network, Nature.com Blogs and a bunch of other social sites use Rails.The jornual platform and other business critical' stuff is Java, though. http://bgyzbaygj.com [url=http://zjmqgfkm.com]zjmqgfkm[/url] [link=http://zsrvuaknc.com]zsrvuaknc[/link] | July 06, 2015

Yeah, Precedings, Network, Nature.com Blogs and a bunch of other social sites use Rails.The jornual platform and other business critical' stuff is Java, though. http://bgyzbaygj.com [url=http://zjmqgfkm.com]zjmqgfkm[/url] [link=http://zsrvuaknc.com]zsrvuaknc[/link]

You? | July 07, 2015