Ruby Weekly News 15th - 21st August 2005

T

Tim Sutherland

http://www.rubyweeklynews.org/20050821.html

Ruby Weekly News 15th - 21st August 2005
----------------------------------------

Ruby Weekly News is a summary of the week's activity on the ruby-talk
mailing list / the comp.lang.ruby newsgroup, brought to you by
Tim Sutherland.

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

* Rails docs as a CHM file
--------------------------

Dema transformed the Rails documentation into the CHM format, as used
by Windows Help.

Bill Guindon: "Thx much! Bit spooky tho, just mentioned how much I
liked chm docs to a partner the other day. Gotta check that phone for
bugs."

* Next Maryland Ruby on Rails codefest August 15th 7pm
------------------------------------------------------

Jeff Waltzer annnounced the next Agile Maryland CodeProject code fest.
(Held in Columbia, Maryland, U.S.)

"For this meeting we will be attempting to generate mailing lables in
PDF format using Test Driven Development."

* Instiki with SQL backend
--------------------------

Alex Verhovsky announced that wiki-implementation Instiki now has
support for using ActiveRecord and SQLite. Until now it has only been
able to run with WEBRick and the Madeleine persistence layer.

The new backend will provide increased reliability and performance
(once some tuning is done).

Still need to do performance testing, refactor the database for
speed, define indexes, implement some caching etc. In other words,
all the "wizardry" bits. So, I thought maybe I can get some wizards
with Rails production expertise interested to the point of getting
involved at this stage.

* Interview with Chris Harrop - making sure you can make sure the sun
---------------------------------------------------------------------
will be shining
---------------

In this week's SciRuby interview, Ara.T.Howard and Justin Crawford
talk to to Chris Harrop about how Ruby assists his efforts to improve
the reliability of systems running weather and climate models.

Chris works at the Cooperative Institute for Research in Environmental
Sciences, University of Colorado.

Threads
-------

Interesting threads included:

Rio 0.3.3
---------

Christopher Kleckner released a new version of Rio, with expanded support
for CSV files.

"Rio is a Ruby I/O convenience class wrapping much of the functionality of
IO, File and Dir."

####
rio('/etc/passwd').csv(':').columns(0,2,4) > rio('rpt').csv("\t")
####

The above example creates a tab-separated file containing the username,
uid and realname for each user in the unix passwd file.

Ezra Zygmuntowicz: "This is a very nice library. Great docs too. I will
use this heavily."

YAENQ: Variable as a pattern
----------------------------

basi: "How do I tell Ruby to use the content of a variable as the pattern,
rather than interpreting the variable name as a literal?"

The aim was to do something like the following, but with v "interepreted
not as a literal but as a variable name",

v = "aeiou"
"goodness" =~ /[v]/

Adam Sanderson said that the same interpolation that is used in string
literals also works for regular expressions. So the answer is simply

"goodness" =~ /[#{v}]/

The change is the use of #{v} instead of just v. As with strings, the
contents of the #{} can be any expression, so #{'foo'*100} is just as
valid as a simple variable substitution.

Installing MySQL Module on Windows?
-----------------------------------

Christopher Aldridge was having a "tuff time" getting the C extension
mysql-ruby to work on Windows. (It allows Ruby to connect to a MySQL
database server.)

Dema directed him untowards one of his blog entries, which includes a link
to a binary for this extension.

Using it, you can simply drop a single file into your Ruby library
directory without having to compile anything.

Alternatively, ruby-mysql is a pure-Ruby alternative, although it is about
half the speed of mysql-ruby.

object pattern matching
-----------------------

Ara.T.Howard had been thinking about "how one would crawl an object graph
to determine if it matched a specific object".

A modified example:

####
pattern = [ {}, {} ]

object1 = [ { 'one' => 1 }, { 'two' => 2 } ]
object2 = [ { 'one' => 1 } ]

object1.is_shaped_like? pattern # => true
object2.is_shaped_like? pattern # => false
####

James Britt murmured "Isn't there a Ruby project that allows one to run
regexen over object hierarchies?"

Phil Tomson said that the project is Reg, by Caleb Clausen.

| Reg is a library for pattern matching in ruby data structures. Reg
| provides Regexp-like match and match-and-replace for all data structures
| (particularly Arrays, Objects, and Hashes), not just Strings.

Newbie:Differences between arrays
---------------------------------

graham:

| Quick question - I have 2 arrays, one which holds the list of people who
| had access to a system when I last checked (OLD), and and another which
| is the current list of people who should have access (NEW).
|
| Is there some neat syntax in Ruby which would allow me to find the
| people added in NEW who are not in OLD, and then find the people in OLD
| who have need to be delete as they are not in NEW?

William James:

irb(main):005:0> %w(oldb newa newb) - %w(oldc oldb olda)
=> ["newa", "newb"]

irb(main):006:0> %w(oldc oldb olda) - %w(oldb newa newb)
=> ["oldc", "olda"]

any messaging frameworks in ruby
--------------------------------

hsun wanted to know if Ruby has any messaging frameworks, similar to
Java's JMS.

Ara.T.Howard said to look at rb_spread, which allows Ruby to participate
in "Spread reliable multicast groups".

Brian McCallister said that he would shortly be releasing code that allows
Ruby to act as a client with JMS.

Troubles with the installation of RAILS
---------------------------------------

Jan Meskens tried to install Rails on Ubuntu Linux, but got the error
"uninitialized constant Base" upon running the rails command.

It turned out to be a problem with Ubuntu's Rails package, which failed to
include dependencies for some required libraries.

(Ubuntu is based on Debian, which historically split up Ruby's standard
library into many different optional packages. This is changed in
bleeding-edge Debian.)

Generic Parsing Library
-----------------------

Adam Sanderson wondered if there was a generic parsing library for Ruby.

RACC and Rockit were mentioned. They generate parsers from grammars.

For simpler requirements, James Edward Gray II's new library Parse Input
may be of interest.

"Parse Input is a library that aids in parsing generic input with Ruby.
This isn't intended to be a full-blown parser, but instead a chain-saw
tool for data mining arbitrary inputs quickly and easily."

Is there a simpler way to do this?
----------------------------------

Julian Leviston was looking for a simpler way to do

####
file = File.open("/usr/blah/1.txt") do | file |
while line = file.gets
the_string += line
end
end
####

James Edward Gray II:

####
file_contents = File.read("/usr/blah/1.txt")
####

Austin Ziegler said that he prefers the following because it also allows a
`filename' that is a URL to a remote location.

####
require 'open-uri'
contents = open(filename, "rb") { |f| f.read }
####

Additionally, it's "safe for text or binary files on all platforms"
(thanks to the `b' for `binary' in the second argument).

RExpect
-------

entropic_rune wanted to know if anyone was using RExpect, as he was having
problems getting it to run. (It is a library used for automating
interactive console programs.)

James F. Hranicky said that he too had had problems, and had switched to
using the pty and expect libraries, both of which are part of Ruby's
standard library.

He attached an example that uses pty with its own simple `expect'
equivalent.

Why and His Guide Mentioned...
------------------------------

James Edward Gray II observed that "Why the Lucky Stiff and The Poignant
Guide to Ruby are mentioned multiple times in the recent IT Conversations
podcast with Joel Spolsky."

Julian Leviston: "What is why's guide?"

Timothy Hunter: "You are in for a treat! http://poignantguide.net/ruby/".

(X)emacs user unite!
--------------------

Forrest Chang introduced a plan to "beef up" (x)emacs support for Ruby,
including improvements to the refactoring browser, and the addition of
code completion.

For the latter, Daniel Debertin directed attention to the ECB - Emacs Code
Browser project.

| It's a code-browser that uses the Semantic engine underneath to provide
| intellisense-like features. If you're using a language that's supported
| by Semantic (c, c++, Java, Python, some others), ECB is a great tool.
|
| Why is this germane to Ruby, you may ask? I'm 90% finished with a
| Semantic grammar for Ruby, and it will probably be released as part of
| Semantic in the near future. Which means you get completion,
| intellisense, and Class/Module/method mapping in ECB for free.

seek/sysseek 64 bit support under Windows
-----------------------------------------

Adam tried to open a disk device in Windows, but couldn't seek beyond 2
GB. The same did work in Linux.

Nobu said his [large file patch] solves this problem.

Adam thanked him, and asked why the patch hadn't been merged into Ruby
CVS. There was not (yet?) a reply.

gem & rdoc: How to avoid "Could not find main page name"
--------------------------------------------------------
warning when using gems?
------------------------

Thomas: "When I automatically the rdoc documentation of a gem I made, I
always get this error/warning. I know there is a rdoc command-line option
for defining the main page when invoking rdoc from the command line. But
how do I pass this option from via a gemspec?"

Chad Fowler directed him to the rdoc options section of the RubyGems
documentation.

templating system
-----------------

Horndude77 wondered if there were any general purpose templating systems
for Ruby, suitable for generating HTML or LaTeX.

Devin Mullins motioned to ERb, which is part of Ruby's standard library.

Paul added that the book Code Generation in Action by Jack Herrington
includes many examples of ERb usage.

NEWBIE QUESTION: pattern with nil
---------------------------------

basi was tired of typing

####
if a == "" or a == nil
if a != "" and a != nil
####

"I'm sure there is a Ruby way to do this."

David A. Black said that you can "normalize" the object to a string: if
a.to_s.empty? or unless a.to_s.empty?.

Wilson Bilkovich said that Rails defines the method Object#blank? as
returning true for objects which are empty? (initially, or after strip),
those which are zero?, and false/nil.

There was a long discussion on what nil? and empty? should mean.

$SAFE >= 2
----------

Mark Volkmann quoted the Pickaxe as saying that setting $SAFE >= 2
"prohits loading program files from globally writable locations".

| Can somewhat clarify what counts as a "globally writable location"? In
| the context of Windows, does it mean that you can load program files
| from any directory of a local hard drive unless it is shared?

Konstantin Levinski explained that it has to do with file permissions:
`globally writable' means that any local user can modify the file.

(And therefore change it to have code that you don't want to run.)

It has nothing to do with the possibility that the code is shared over
some sort of network filesystem.

ruby-dev summary 26662-26760
----------------------------

Minero Aoki summarised the Japanese mailing list ruby-dev.

Included is reference to a patch by Tadashi Saito that roughly doubles the
speed of calculations involving Fixnums (small integers).

It achieves this by reducing the number of Fixnum#coerce calls. "Matz
accepted this patch."

Case Expressions and Classes
----------------------------

Daniel Schierbeck asked why the following code displays `no'.

####
case :foo.class
when Symbol then
puts 'yes'
else
puts 'no'
end
####

James Edward Gray II explained that case works by comparing objects with
===, and not == as you might assume.

In this case it calls Symbol === :foo.class.

For classes, === checks whether the parameter is an instance of the class.
:foo.class is Symbol, which is not an instance of Symbol, so
Symbol === :foo.class is false.

"Put another way, you're outsmarting Ruby's very intelligent case
statement. Let it do all the work:"

####
case :foo
when Symbol
puts 'yes'
else
puts 'no'
end
####

Now :foo is an instance of Symbol, so Symbol === :foo is true.

Ara.T.Howard gave a more detailed explanation of case, and included more
examples of the sort of matches that can be performed:

####
case obj
when String, Fixnum, Array
when File
when %r/foo/, %r/bar/
else
end
####

Sodoku Solver (#43)
-------------------

This week's Ruby Quiz comes from quiz-maestro James Edward Gray II. The
task is to write a program that can solve Sodoku puzzles.

See also the SuDoku-X Solver thread.

| Ruby Quiz is a weekly programming challenge for Ruby programmers in the
| spirit of the Perl Quiz of the Week. A new Ruby Quiz is sent to the Ruby
| Talk mailing list each Friday. (Watch for the [QUIZ] subject
| identifier.) After a 48 hour no-spoiler period has passed, everyone is
| invited to contribute solutions and/or discussion back to the list. The
| following Thursday a Summary will be sent to the list, discussing the
| quiz, solutions and discussion. The next day, the cycle begins again.

is there a shorter way to compare these 2 objects?
--------------------------------------------------

Lowell Kirsh asked if there was a simpler way to implement <=> in the
following class:

####
class Foo
attr_accessor :a, :b, :c, :d

def <=>(rhs)
if (@a <=> rhs.a) != 0
@a <=> rhs
elsif (@b <=> rhs.b) != 0
@b <=> rhs.b
elsif ....
end
end
end
####

(<=> is the `spaceship operator', used to compare two objects for
ordering. It returns -1, 0 or 1 depending on whether the first object is
less than, equal to, or greater than the second.)

James Edward Gray II suggested:

####
def <=>( other )
[@a, @b, @c, @d] <=> [other.a, other.b, other.c, other.d]
end
####

It works because Array#<=> compares its elements in lexicographical order.
(i.e. the same way as Lowell was doing by hand in the first <=>
definition.)

James also mentioned the Comparable mixin. Including Comparable in Foo
will gain it methods such as Foo#==, Foo#> and Foo#between?.

Robert Klemme gave three alternative implementations of Foo#<=>, using the
name of the fields and send, while Simon Kroeger proffered:

####
def <=>( other )
(@a <=> other.a).nonzero? ||
(@b <=> other.b).nonzero? ||
(@c <=> other.c).nonzero? ||
(@d <=> other.d)
end
####

This is an interesting solution because it uses the fact that nonzero?
returns either nil or self. (Rather than false/true.)

"string"[0.."e"]
----------------

basi wanted to index a string via a pattern. The code below demonstrates
the sort of behaviour that was desired, although it does not work:

"astring"[0../r/] # "ast"
"astring"[/ast/..-1] # "ring"

Joel VanderWerf set forth:

"astring"[/.*?(?=r)/] # --> "ast"
"astring"[/ast(.*)/, 1] # --> "ring"

He explained, "The (?=r) is a lookahead operator that matches but does not
consume characters. The numerical argument n=1 in the second example
indicates that #[] should return the value of the n-th capture".

The numerical argument could also be used to re-implement the first line
without using the lookahead operator:

"astring"[/(.*?)r/] # --> "ast"

As an alternative, William James said that you could instead use
String#sub to remove the part of the string you don't want to match.

"astring".sub(/r.*/, '') # --> "ast"
"astring".sub(/^ast/, '') # --> "ring"
 
T

Tim Sutherland

http://www.rubyweeklynews.org/20050821.html [...]
(Ubuntu is based on Debian, which historically split up Ruby's standard
library into many different optional packages. This is changed in
bleeding-edge Debian.)
[...]

Thanks to Paul van Tilburg for pointing out that this remark was incorrect.

The current stable and development releases of Debian all do the right
thing.
 
T

Tim Sutherland

Below, a correction.

http://www.rubyweeklynews.org/20050821.html [...]
Joel VanderWerf set forth:

"astring"[/.*?(?=r)/] # --> "ast"
"astring"[/ast(.*)/, 1] # --> "ring"

He explained, "The (?=r) is a lookahead operator that matches but does not
consume characters. The numerical argument n=1 in the second example
indicates that #[] should return the value of the n-th capture".

The numerical argument could also be used to re-implement the first line
without using the lookahead operator:

"astring"[/(.*?)r/] # --> "ast"
[...]

Thanks to Tobias Reif for the following correction. It helps if we actually
include the fabled numerical argument:

"astring"[/(.*?)r/, 1] # --> "ast"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top