Ruby

From the FAQ [L1 ] (escargo 16 Jan 2008 - This gives a file not found error.):

“Ruby is a simple and powerful object-oriented programming language, created by Yukihiro Matsumoto (who goes by the handle "matz" in this document and on the mailing lists).

“Like Perl, Ruby is good at text processing. Like Smalltalk, everything in Ruby is an object, and Ruby has blocks, iterators, meta-classes and other good stuff.

“You can use Ruby to write servers, experiment with prototypes, and for everyday programming tasks. As a fully-integrated object-oriented language, Ruby scales well.”

RLH Scales well? In what way?

Ruby doesn't have true threads and is known to have performance issues, a quote from a rant of a long-time Ruby user [L2 ] notes about RoR:

“The main Rails application that DHH created required restarting _400 times/day. That's a production application that can't stay up for more than 4 minutes on average.”

The home page for Ruby is http://www.ruby-lang.org/

Its most articulate advocates write such descriptions as,

“... it has a couple of real killer features; in particular the way blocks and the pervasive use of the visitor pattern come together change the way one writes programs for the better.”

A lot of the attention Ruby has gotten lately is due to Ruby on Rails[L3 ].

During Oct 2007, [L4 ] was making "Build Your Own Ruby on Rails Web Applications" available in PDF format for free...

This author summaries Rail's guiding principles as:

  • convention over configuration (assumptions for defaults rather than requiring extensive initial configuration) [L5 ]
  • DRY
  • agile development

See [L6 ] for an intro to Ruby on Rails


There is a Ruby/Tk if you want to bring your Tk skills into a new world:

  require 'tk'
  root = TkRoot.new() { title "Hello, world!" }
  Tk.mainloop()

(from [L7 ]) More on Ruby/Tk (for MacOS!) appears in the "Ruby/Tk Primer: Creating a cron GUI Interface with Ruby/Tk" [L8 ].

Note, however, that at least one survey [L9 ] suggests that acceptance of RubyTk is dwindling.


 What: Ruby
 Where: http://www.ruby-lang.org/  
        http://www.rubycentral.com/book/ext_tk.html  
        http://poignantguide.net/ruby/ 
 Description: Programming language for quick and easy programming.
        A clean, consistent language design where everything is an object,
        CLU style iterators, singleton classes/methods, and
        lexical closures.  Makes use of Tk (with bindings similar in
        concept to Perl/Tk) for its GUI support.
        Currently at version 1.8.4 .
 Updated: 08/2003
 Contact: mailto:[email protected]  

See [L10 ] for more information. (escargo 16 Jan 2008 - This gives a file not found error. This link [L11 ] is about Ruby Tk.)

This [L12 ] review of Ruby Cookbook tries to give a sense for how Ruby feels.


RS: Like Scheme, Ruby has arbitrary-size integers as default - another hint that Tcl should have it too... Octet-packed integers come to mind..

AK: I consider the Octet-packed integers more something of a file-format, and less of an in-memory format. Note aside: In Slim Binaries I refer to the paper about Universal Symbol Files. This paper advances the notion of octet-packed integers too, albeit slightly differently than metakit if I read the code right. - RS: Well, a very simple alternative would be to just keep the string rep and let expr work on that if it runs into a "integer value too large to represent".

NEM notes in Jan 2008 that Tcl 8.5 does indeed now have arbitrary-size integers.


See [L13 ] for one comparison of Ruby to C++, CLOS, Dylan, Java, Objective C, Perl, PHP, Python, Smalltalk,


Ruby vs Tcl:

http://journal.dedasys.com/articles/2006/03/06/ruby-vs-tcl

APN My personal experience with Ruby is that it is indeed a fun language to program in as claimed. However, fun does not necessarily equate to productivity and I find Tcl much more productive without losing any of the fun part of it.


ruby-tcl apparently lets you create Tcl interpreters from within Ruby. The author, Sam Stephenson, unveiled it at RubyConf 2008 during his talk, "Tcl for Rubyists", which you can watch at [L14 ] (the demo begins around 40 mins 15 secs). The code itself can be downloaded from [L15 ].


iu2 A small comparison: Given the file data.txt that contains numbers "1 2 3 4..10". We want to sum the multiplications of pairs, that is, 1*2 + 3*4 + 5*6..., here are some snippets:

tcl

  set fid [open data.txt r]
  set txt [read $fid]
  close $fid

  set sum 0
  foreach {x y} $txt {
    incr sum [expr {$x * $y}]
  }
  puts $sum

python

  with file('data.txt') as f: txt = f.read()
  nums = map(int, txt.split())
  pairs = [nums[i:i+2] for i in range(0, len(nums), 2)]
  s = sum(x * y for x, y in pairs)
  print s

ruby

  sum = open('data.txt', 'r') {|f|
    f.read.split.map {|a| a.to_i}.each_slice(2).inject(0) {|sum, pair| sum + pair[0] * pair[1]}
  }
  puts sum

Dec The Tcl, although I would code it slightly different, and Python snippets are quite readable, which to me is good coding style, the Ruby snippet...

Mirell Whoever wrote that Ruby should be shot, and I think it's trying to be intentionally obtuse.

ruby

  sum = 0
  IO.read("ruby-numbers").split.each_slice(2) {|a,b| sum = sum + a.to_i * b.to_i}
  puts sum

And done. Less lines than Tcl, and not as intentionally obtuse as the above example.

DKF: Putting lots of stuff on a line is good style in Ruby? I guess that's a style difference with Tcl; we tend to prefer to use more newlines, spreading our code out...

makr (2009-11-23): Yes, in other languages (e.g. Java) this kind of coding is called a Trainwreck. Good coding practice as e.g. in The Law of Demeter should prevent this and ensures maintainability of the code. So it is not cool to say: See, I can do more in only one line than you could! but to say: See, I can still read and understand the code half a year after I wrote it! ...

diam 16/03/2010 I agree that fewer line doesn't mean better code! But the ruby version of the tcl code above could be written more tcl like :

ruby (shortest yet readable)

  txt = File.read "data.txt"
  sum = 0
  txt.split.each_slice(2) do |a,b| 
      sum += a.to_i * b.to_i 
  end
  puts sum

ruby shouldn't be that iterative

nakilon: method chaining should be used

  puts File.read("data.txt").split.map(&:to_i).each_slice(2).
    inject(0){ |s,(a,b)| s + a * b }

AM (12 august 2009) I am not sure I understand the complete concept of code blocks well enough, but Tcl has code blocks too:

    set block {puts $elem}
    foreach elem $list $block

is an - admittedly - primitive example. One awkward aspect of course is the use of a local variable in the block of code, but that can be taken care of:

    set block {puts $elem}
    foreach elem $list {apply {{elem block} {eval $block}} $elem $block}

or via:

    proc block {vars code} {
        foreach v $vars {upvar 1 $v $v} 
        eval $code
    }
    set block {puts $elem}
    foreach elem $list {block {elem} $block} 

DKF: Tcl doesn't bind variables at the block level, but rather at the level of the procedure (or lambda term) so instead we'll normally use the caller's context. It's a different way of doing things.


PYK 2014-10-09: An excerpt from the Tcl Chatroom, 2014-10-09:

dkf [17:06]
I've been wrestling on and off with Ruby for a while; my God, they really have no idea what to do with string encodings?!
dkf [17:08]
The problem is that they keep every string in its original encoding. Nice and fast. And if you've got strings in two different encodings (e.g., UTF-8 and ISO-8859-1) then guess what? They just concatenate the bytes! Yes! BROKEN!
dkf [17:09]
If you're lucky, you get extra noise characters from stuff getting converted into 8859-1; if you're unlucky, something downstream chokes on the illegal UTF-8…

Rails-like (object-relational) web frameworks in Tcl: