Ruby Weekly News 14th - 20th February 2005
		   ------------------------------------------

   A summary of the week's activity on the ruby-talk mailing list / the
   comp.lang.ruby newsgroup. This summary is brought to you by Tim Sutherland
   (TimSuth).

Articles and Announcements
--------------------------

     * [Ruby Meetup Groups]

           There were several posts this week from people announcing that
           they had created [meetup.com] groups to try and find Rubyists in
           their area. Curt Hibbs posted a link which lists [all Ruby
           meetup.com groups]. There are around 50 so far, with most only
           having one active member at the moment - this is a good
           opportunity to add yourself to a list in your area. Zach Dennis
           started a thread suggesting a [Virtual Ruby Group] where people
           meet by "microphone/webcam/instant messenger/irc channel, etc.. to
           do a meeting over the wire".

     * [ICFP Contest Dates Are Set]

           James Edward Gray II noted that the "International Conference of
           Functional Programming has announced dates for their annual
           programming contest." The problem will be announced on June 24th
           2005 with final entries due on July 10th.

     * [Ruby Visual Identity Team]

           A team is being set up to improve the [ruby-lang.org] website. See
           Threads for more discussion of this.

Quote of the Week
-----------------

   A [series] of quotes rather than a single one this week. It all started
   when Francis Hwang announced a library that "mocks" out File, FileUtils,
   Dir, and other classes to make it easier to write unit-tests that depend
   on these.

   Francis Hwang: "I'd mock out the air itself if my lungs were
   hot-swappable".

   Ben Giddings: "If you ever decide to mock out a human being, let me know.
   This morning in the shower I was wondering how I can mock out the person
   who has to push a button on an embedded device I'm working on. Sure, I can
   easily mock out the register that pushing the button supposedly changes,
   but that kinda defeats the purpose of the test."

   Ilmari Heikkinen: "Robots, man, robots. Preferably small dancing ones."

   Daniel Berger: "You smell and your momma dresses you funny. How's that?
   Oh...mock "out". ;)"

Threads
-------

   Interesting threads this week included:

  [What is this syntax?]
  ----------------------

   David Corbin didn't understand what the '*' was doing in the following
   code

  def foo(*)
  end

   E S explained that it was similar to

  def bar(*a)
  end

   meaning that the bar method takes any number of arguments. The difference
   is that in the second case, the arguments are available as the Array a. In
   the code David posted, the arguments to foo are ignored.

   So foo takes any number of arguments and ignores them all.

  [Rails FastCGI deployment problem]
  ----------------------------------

   Some students of Robert Feldt had developed a [Rails] application on
   Windows, and then wanted to deploy it on a Linux server running Apache
   with FastCGI.

   The Apache error log gave messages like "FastCGI: can't start
   server"/home/railsapp/railsapp/public/dispatch.fcgi" (pid 14780), execle()
   failed: No such file or directory".

   Navindra Umanee correctly guessed that the first line of
   /home/railsapp/railsapp/public/dispatch.fcgi was wrong. The line should
   have pointed to the Ruby interpreter, but the path it gave was incorrect.
   For example, the line might have been "#!/usr/bin/ruby" instead of
   "#!/usr/local/bin/ruby".

  [interacting with ruby program]
  -------------------------------

   Navindra Umanee asked if there were "any nice or existing solutions for
   attaching to a running Ruby process and changing the code on the fly from
   the console?" Florian Gross directed him to the 'breakpoint' library (part
   of [Rails]). This allows you to set breakpoints in programs and get an irb
   prompt when the breakpoint is hit. It even works remotely.

  [iconv.so is not installed with the mswin version of ruby?]
  -----------------------------------------------------------

   robert.wilder was using REXML to read some files encoded in Shift_JIS
   (Japanese encoding). He was getting an error "uconv or iconv is required
   for Japanese encoding support".

   Robert noted that there is already a bug report filed for this issue with
   the One-Click Ruby installer for Windows, but wondered what to do in the
   meantime.

   Assaph Mehr gave a workaround, which involves extracting iconv.so from the
   ruby-1.8.2-i386-mswin32.zip distribution on the main Ruby site, then
   getting iconv.dll from dll-files.com. Robert confirmed that this solved
   his problem.

  [Corporate RubyGems Repository]
  -------------------------------

   Roustem Karimov was working on some in-house Ruby projects and wanted to
   use RubyGems to install and manage these across multiple servers. He set
   up an internal RubyGems repository and everything worked. An annoyance he
   had to deal with was creating the /yaml file containing all the gemspecs.
   Was there a tool to automate this?

   Chad Fowler said he had two options. One was simply to run the gem_server
   program, which would handle everything. Alternatively, a program called
   generate_yaml_index.rb is available to generate the yaml file.

   Jim Freeze asked why Roustem didn't just install each application just
   once, on a shared directory. Roustem replied, saying that this idea can be
   more difficult to do than it sounds - for example, you have to deal with
   firewalls between servers.

  [SIGALRM available?]
  --------------------

   Guillaume Marcais asked if Ruby applications were allowed to use the
   SIGALRM signal, or whether it was reserved for internal use. Matz said
   that SIGALRM can be used freely, but SIGVTALRM cannot - it is SIGVTALRM
   that is used in Ruby's threading implementation.

  [FAQ for comp.lang.ruby]
  ------------------------

   hal9000 posted the FAQ for comp.lang.ruby. This includes posting
   guidelines, so if you're using the newsgroup, it's a good idea to check
   out the FAQ first.

  [Combining IOs and Strings?]
  ----------------------------

   Derek Lewis wanted to write a method appendTo(a, b) that combines a and b,
   where the arguments are either Strings or IO. If they are Strings it's
   easy: a+b. If they were IO objects though, he wanted to avoid having to
   read all the data from them to turn them into Strings.

   "What I'd like to do is return an IO from the method, that, when read
   from, will return the data from someData, and then the data from
   moreData."

   "Is there a particular subset of the methods in IO that I can override in
   an IO subclass, and be confident that my subclass will work?"

   Eric Hodel pointed him towards the StringIO class. (StringIO takes a
   String and returns an object which behaves like an IO instance, with
   methods like #read and #write.) Derek's class should implement the same
   methods as StringIO.

  [[SOLUTION] Yahtzee (#19)]
  --------------------------

   James Edward Gray II posted his solution to last week's [Ruby Quiz],
   starting with the following quote:

   "When I was young, I was in a programming club that often had us build
   working programs from simple games. Blackjack, Yahtzee, etc. There was
   usually a twist though, like a time limit or having to create the game on
   your TI calculator. In that club, I built Yahtzee in just under one hour."

  [Reading mp3 files]
  -------------------

   Scott Rubin wanted to extract information from MP3 files, for example
   bitrate and playtime.

   Stefan Holst said he'd written a library called xiron which wraps the
   xine-lib media playing library. It's fairly new and hasn't been discussed
   on ruby-talk before, but it works. It allows you to write code like

  require 'xiron'
  s = Stream.new(VideoPort.none, AudioPort.none)
  s.open("foo.ogg")
  puts(s.length)
  puts(s.title)
  puts(s.bitrate)

  [Curious regexp behavior]
  -------------------------

   Derek Lewis did an experiment to see which was faster:

  total = 0
  File.open( 'words', 'r' ) { |file|
      file.each_line { |line|
          word = line.chomp
          total +=1 if word =~ /[a-df-h][aeiou]{2}/
      } 
  }   
  puts total

   or

  rexp = /[a-df-h][aeiou]{2}/
  total = 0
  File.open( 'words', 'r' ) { |file|
     file.each_line { |line|
         word = line.chomp
         total +=1 if word =~ rexp
     }
  }

   He expected that the second one would be faster, reasoning that in the
   first piece of code, a new regular expression object is created for each
   line. In fact, the first was slightly faster.

   Charles Mills and Eric Hodel explained that a literal regexp is part of
   the AST (Abstract Syntax-Tree) of the program. This means that Ruby
   creates the regexp just once - at "compile-time" when the program is
   parsed.

   Ryan Davis used his ParseTree library to demonstrate what was happening.
   "a=/blah/; 's' =~ a" is parsed as

  [:lasgn, :a, [:lit, /blah/]],
        [:call, [:str, "s"], :=~, [:array, [:lvar, :a]]]]]]]]

   "'s' =~ /blah/" is parsed as

  [:match3, [:lit, /blah/], [:str, "s"]]]]]]]

   In the second case, Ruby not only treats the regular expression as a
   literal (avoiding the variable lookup), but it recognises that a regexp
   match is being done and constructs a "match3" node to do the comparison.
   In the first case, a method call to String#=~ must be performed.

   A disadvantage of Ruby's "match3" optimisation is that overriding
   String#=~ may not work as you expect. For example,

  class String
    def =~(regexp)
      puts("HOW ARE YOU GENTLEMEN !!")
    end
  end
   
  's' =~ /foo/    # -> no output
  's'.=~ /foo/    # -> "HOW ARE YOU GENTLEMEN !!"

  [Wee web-framework. It's great!]
  --------------------------------

   Joao Pedrosa was impressed with the Wee web-application framework, saying
   "Wee is awesome. I still need to workout a full example, but Wee has been
   behaving the way I expect, so I wanted to say a *thank you* to Michael for
   creating a truly gem."

   Joao later posted a long message explaining what makes Wee so great. A
   couple of interesting paragraphs:

   "GUI is generally divided in components/widgets, right? The problem is
   that in the web, GUI components happen to exist in the browser (client),
   but most of the business logic and state comes from the server. In a
   normal web-page, you may have more than a FORM tag. So when one is
   submitted, you may lose what has been entered in another FORM. You may
   need to handle the BACK browser button. And you may need to handle the
   Session, that is the maintenance of the state between browser requests.
   Now, imagine arbitrary GUI components that happen to be in the same
   web-page. Imagine each component with its own state and responding to
   events. That's a lot to imagine, but have no fear, because Wee is here."

   "Wee supports the GUI componentization for a web-app. You no longer need
   to worry about everything by yourself (mainly about keeping everything in
   sync), because Wee can handle a lot by itself. Not only that, but the HTML
   generation is nice ruby code, with closures, blocks, etc. The components
   will work together in the same page or in different pages. Unload your
   work to them, and they will handle it. You no longer need to worry about
   URLs, for instance. Just "call(Component.new)" and it's like going to the
   next page. Just "answer" and the previous component takes care."

   Michael Neumann (the author of Wee) gave some concrete examples of this.
   (Wee can use continuations.)

  [Marick's testing book (Ruby-based)]
  ------------------------------------

   Brian Marick is writing a book called Scripting for Testers to help people
   without a programming background write test code in Ruby. "So the request
   for help: what do you think of that? What kinds of tasks should be
   covered? What tools should I talk about?"

  [Python at SIAM conference]
  ---------------------------

   Bil Kleb said "[t]here were several sessions devoted to "scripting"
   languages during last weekend's Computational Science and Engineering
   conference -- the talks were 95% Python and 5% Perl."

   "Had I known, I would have snuck a Ruby talk in there..."

   The conference is next held in two years time. It would be good to see
   some Ruby content then.

  [ruby-dev summary 25642-25708]
  ------------------------------

   SASADA Koichi posted the latest summary of the Japanese list ruby-dev. It
   included a post by Shugo Maeda proposing a hook function like
   set_trace_func, but lower-level and only available in C. Shugo had used
   this to implement a high-performance profiler.

  [Ruby + end user applications]
  ------------------------------

   martinus got some good feedback from users of XDCC-Fetch (a tool for IRC).
   A couple of them said that this program had inspired them to learn Ruby.
   "Ruby definitely needs more cool, simple to use, end user applications."

   In the past, almost all public Ruby projects were libraries for Ruby, with
   people using these libraries for "internal" work. That seems to be
   changing with more applications written in Ruby coming out.

   The thread discussed some of these, as well as ideas for other end-user
   applications. Martin DeMello pointed out [glark], which is a 'better
   grep', with features like highlighting matches. [Watir] was also listed
   (by James G. Britt). This is a web testing framework which utilises IE.

   martinus ended up creating a [list of software project ideas] on
   tadalist.com.

  [[SUMMARY] Yahtzee (#19)]
  -------------------------

   James Edward Gray II summarised last week's [Ruby Quiz] - to implement the
   Yahtzee dice game.

  [2/24 = 0?; or, how do I add hours to a DateTime?]
  --------------------------------------------------

   Roy wanted to add two hours to a DateTime. His initial problem was that
   2/24 was returning 0 when he expected 0.08333... wannes explained that he
   was doing integer division, and that 2/24.0 would give the result Roy was
   expecting.

   Sam Roberts warned "[r]emember that the trivial "convert your units to
   seconds and add it to Time" doesn't work in the face of leap years,
   daylight savings time, etc, but Date has knowledge of this that you can
   exploit." He also posted some code that adds plus_year, plus_month and
   plus_day methods to Time. It would be easy to add a plus_hour method in
   the same vein. They work by calling Time.local(year, month, day, hour,
   min, sec, usec) with the updated values.

   Phrogz pointed out his MutableTime class which wraps time and allows code
   like mtime.hours += 2.0/24. It works by doing things like time +
   3600*hours, so suffers from the problems described by Sam.

  [[QUIZ] 1-800-THE-QUIZ (#20)]
  -----------------------------

   James Edward Gray II announced this week's [Ruby Quiz].

   "Many companies like to list their phone numbers using the letters printed
   on most telephones. This makes the number easier to remember for
   customers. A famous example being 1-800-PICK-UPS."

   This week's quiz is to write a program that will show a user possible
   matches for a list of provided phone numbers." (Using a dictionary file.)

  [Notes on PDF::Writer's next release...]
  ----------------------------------------

   Austin Ziegler had noticed a lot of interest in his PDF::Writer library,
   used to create PDF files. "The good news is that there's going to be a lot
   of enhancements", including proper image support, better support of PDF
   options, primitives, fonts, tables and colours (RGB and CMYK). The bad
   news is that the API will also change drastically.

   "I think that this will be a very exciting release. Watch for it in early
   March."

  [Where is Ruby headed etc.] [Ruby Visual Identity Team] [Ruby Visual Identity
  Team: Project, Mailing List, and Wiki]
  -----------------------------------------------------------------------------

   Glenn asked "where is Ruby headed?". The thread ended up discussing the
   official Ruby website and how to improve it. Matz set out a plan:
     * form a team to design the appearance
     * form another team to choose the CMS
     * create prototype on that CMS
     * www-admin would replace www.ruby-lang.org

   Several people volunteered to help, and the thread continued under "Ruby
   Visual Identity Team". Matz was keen to see more English-writing people on
   the www-admin team, to write announcements in English.

   Curt Hibbs created a public mailing list [vit-discuss] for co-ordinating
   the team and encouraged all those interested to join.

  [Rails presentation]
  --------------------

   Jamis Buck presented [Rails] to over 100 programmers at the Utah Java
   Users Group. He gave them some performance metrics to try and overcome the
   perception that Rails must be slow because it's dynamic. Eric Hodel
   corrected one of these metrics - Jamis had reported that [43things.com]
   served of 6 pages a second on one server at peak times, in fact the
   performance is much better, with up to 180 pages per second. (6 pages/sec
   per FastCGI process, of which there are 30.)

   Asked for advice on giving Rails presentations, Jamis had some ideas for
   what he would do differently next time: keep the action in the video close
   to the top of the screen so people at the back can read it, use a
   high-contract syntax highlighting scheme and repeat every question that is
   asked before answering it.

   "They _really_ loved that Rails uses WordNet to suggest model and
   controller names when there is a conflict. :) If I had it to do over
   again, I'd probably use more little things like that in the presentation."

  [[rcr] Array#join non string arguments]
  ---------------------------------------

   Simon Strandgaard proposed changing Array#join to allow

  [1, 2, 3, 4, 5, 6].join(0)    #-> [1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6]

   Matz said that this behaviour could be useful, but it should not be called
   Array#join - "I think behavior that changes depends on indirect types
   (i.e. type of elements in the receiver this case) is not good idea. A
   method gives a string should always gives string (or string-like object)".

   It would also break the current usage of Array#join, for example

  ['a', 'b', 'c'].join('-')     #-> ['a', '-', 'b', '-', 'c'] or 'a-b-c'

   Jannis Harder suggested "interpolate" ("interleave" was also considered),
   with an optional block. For example,

  [8,6,4,2,0].interpolate{|a,b|(a+b)/2}  #-> [8,7,6,5,4,3,2,1,0]

   He also gave an example where interpolate was passed multiple arguments.

New Releases
------------

     * [Nitro + Og 0.10.0]

           George Moschovitis released new versions of Nitro (web application
           framework) and Og (object-relational mapping library). Og now
           supports SQLite3, optional type-checking, has cleaner code and
           better examples. Nitro has a new configuration system.

     * [FileSystem 0.1.0: Beta for me, Alpha for you]

           Francis Hwang introduced the first public release of FileSystem:
           "a library that will mock out File, FileUtils, Dir, and other
           file-dependent built-in classes. It aims to simulate an entire
           file-system in memory for the purposes of testing." The name of
           the project will likely be changing in the future, as "FileSystem"
           conflicts with a different ibrary by Mike Hall of the same name.

     * [PageTemplate 1.1]

           Brian Wisti added 'include' functionality to PageTemplate, a
           library for using text templates (for example, with web programs).
           Features include variable substitutions, if-else blocks, loops and
           caching. Version 1.1.1 was released a few days later, fixing some
           documentation bugs and making the library available under
           RubyGems.

     * [Ruby Bindings for POI]

           Avik Sengupta wrapped the Java library POI (used to read and write
           OLE2 Compound Document Files like the Microsoft Excel format). He
           wrapped it by compiling the Java code with GCJ to turn it into a
           native library which was then wrapped with SWIG.

     * [FaceToFace 0.1.0]

           Benny was "happy to announce his first published piece of
           software", FaceToFace. "You may think of it as syntactic sugar and
           as duck-typing taken to the next level (imagine two ducks face to
           face, none of them being a real duck)." It used used for type
           conversions, for example 5.to(String) or String.from(5).

     * [YARV: Yet Another RubyVM 0.1.1]

           SASADA Koichi has been busy at work on YARV, a virtual machine for
           Ruby. New optimisations include an experimental JIT. It's now
           easier to test out YARV - you can do either ruby foo.rb to use the
           normal Ruby interpreter or ruby -rite foo.rb to use YARV.

     * [FXIrb 0.14 - a Win32 GUI wrapper around IRB]

           Martin DeMello released an alpha of FXIrb: a GUI around irb
           (Interactive Ruby). Currently it only runs on Windows, but will be
           ported to other systems in the future.

     * [SQLite3/Ruby 1.1.0]

           Jamis Buck updated the Ruby binding for the SQLite3 embedded
           database system. A Database#query method was added to allow
           iterating over a result set without using a block. Several bugs
           were also fixed.

     * [aeditor-2.4 (turbo release)]

           Simon Strandgaard added syntax highlighting to AEditor, an editor
           for programmers.

     * [ruby2c 1.0.0 beta 2 released]

           Ryan Davis released the second beta of ruby2c 1.0.0. RubyToC is
           used to translate a subset of Ruby into C. Its authors want to use
           it to rewrite core Ruby libraries in Ruby instead of C, in a
           similar fashion to some implementations of the Smalltalk language.

     * [Syck 0.51: More tests passing, cleaner output]

           why the lucky stiff offered a 'hello' to "all you mangy
           listdwellers". To make amends for this insult, he also offered an
           experimental new version of Syck, the YAML processor which comes
           with Ruby. (YAML is a markup language.)