Seeking Contributions for O'Reilly's Ruby Cookbook

L

Leonard Richardson

Hello, all,

Lucas Carlson and I are happy to announce that we're working on a Ruby
Cookbook for O'Reilly. We've hit our stride in the writing and I'm
taking on the task of soliciting and managing contributions from the
larger Ruby community. I ask everyone with an idea for a recipe, an
itch to do a bit of expository writing, or an unslakable lust for peer
review to get in touch with me.

For more details, including a rough outline and the kinds of recipes
we'd like to see more of, please see:

http://www.crummy.com/writing/RubyCookbook/

Leonard

PS: I didn't announce this on c.l.r previously, but the Rubyful Soup
screen-scraper is now at 1.0. It's as good as Beautiful Soup, but with
Ruby idioms:

http://www.crummy.com/software/RubyfulSoup/
 
D

David A. Black

Hi --

Be careful with that. PLEAC entries are translated from the Perl
Cookbook. PLEAC gained permission to do this. That permission may or
may not apply to further use.

I'd add that I was told at one point by the PLEAC Ruby maintainer (or
one of the maintainers) that the goal was not to show the
"peculiarities" of individual languages (such as, if I remember
correctly, iterators in Ruby), but rather to show what the languages
had in common, or words to that effect. I ended up concluding that it
was basically Perl being transliterated into many languages.


David
 
G

Gavin Sinclair

David said:
I'd add that I was told at one point by the PLEAC Ruby maintainer (or
one of the maintainers) that the goal was not to show the
"peculiarities" of individual languages (such as, if I remember
correctly, iterators in Ruby), but rather to show what the languages
had in common, or words to that effect. I ended up concluding that it
was basically Perl being transliterated into many languages.

Yeah, that's of little concern to someone writing a fresh cookbook,
though. The real question is: is it fair game to use the _problems_
that the Perl Cookbook addresses. Of course you would create genuine
Ruby solutions rather than attempt a translation.

If it's legally acceptable to use the Perl Cookbook's questions, a
subset of them would make a great start towards a Ruby Cookbook. All
that's required is the effort...

Gavin
 
P

Peter Hickman

Well we could start with a couple of chapters for ideas

Databases
Using dbi to access your database
Quick and easy databases with sqlite
Using activerecord

XML
Creating XML documents
Processing XML with REXML

Net
Automating web access with net/http
Using SSL for secure web access
Using Webrick
Using the Flickr API

Websites
Custom cgi scripts
Page templating for automatic site building
Forms processing

Basically we just need to think of things in terms of a user asking "How
do I ..."

Just think of things that you can do with Ruby that other people will
also want to do.
 
P

Peter Hickman

Got me thinking, maybe the first chapter

Introduction
Installing Ruby
Updating your Ruby installation
Using gem package management
Finding and installing new packages with gem
Installing other packages from source
Using the documentation

plus

GUI
Quick and simple apps with Ruby/Tk
Crossplatform GUI applications with Fox

The second edition of the perl cookbook is over 800 pages long with 414
entries, the XSLT cookbook is over 640 pages which gives perl at 2 pages
an entry and XSLT at over 6. I take it we are looking at perl size
entries more than XSLT, perhaps 200 entries at around 400 pages.

Something on SDL perhaps, create your own CD / MP3 player.

Sorry if I am going over the same ground as everyone else but I just
noticed this thread.
 
D

Daniel Lewis

I'd like to see details about :
* blocks, closures and yeilding (and using Ruby functionally)
* Ruby/GTK
 
P

Peter Hickman

Daniel said:
I'd like to see details about :
* blocks, closures and yeilding (and using Ruby functionally)
* Ruby/GTK
I speak with no authority (on anything) here but a cookbook is where
someone who has a specific problem looks for a solution, so your first
point would fall outside of the scope of a cookbook, being more of a
'ruby programming techniques' type of question, but the second is
clearly in there. Perhaps I could also add

Documents
Creating PDFs from Ruby
Reading, searching and editing PDFs
Reading and writing excel files
 
D

Daniel Lewis

OK fair enough, instead of Blocks, closures and yielding:
* Using Ruby like a functional programming language (e.g an I/O monad)
* Using Ruby to develop artificial intelligence apps (e.g a simple 2
layer feedforward neural network)
 
J

James Britt

Peter said:
I speak with no authority (on anything) here but a cookbook is where
someone who has a specific problem looks for a solution, so your first
point would fall outside of the scope of a cookbook, being more of a
'ruby programming techniques' type of question, but the second is
clearly in there. Perhaps I could also add

Documents
Creating PDFs from Ruby
Reading, searching and editing PDFs
Reading and writing excel files


I agree; a cookbook is more generally organized around tasks or goals;
that one or another library or tool or technique is involved all depends
on how well it helps solve a particular problem.

James Britt

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
 
H

Hugh Sasse

System administration tasks (lots to choose from).

Email processing: POP, SMTP, IMAP, (bayesian anti-spam?) and
attachments.

XML_stuff.map {|X| X.to_yaml}

And could we really have a Ruby Cookbook without a couple of recipes
for Chunky Bacon?

Hugh
 
L

Leonard Richardson

I see lots of good recipe ideas in this thread; thanks to everyone for
your help. Please keep the ideas coming.

Regarding the Perl Cookbook recipes: many of the recipe ideas in our
outline are in fact borrowed from other O'Reilly cookbooks, especially
the Perl and Python cookbooks. We figured this would be a good starting
point, especially since many elementary recipes show up in more than
one cookbook. But all else being equal, we would prefer to use recipes
that demonstrate Ruby-specific idioms, or give a Ruby twist to recipes
that are common across programming languages.

I agree that the focus of the recipes should be helping people with
specific problems rather than systematically covering aspects of the
language. I think some parts of the cookbook show this focus well (even
at the risk of repeating ourselves across recipes), but other parts
still need work. As with other O'Reilly cookbooks, each chapter will
have an introduction giving a basic overview of the features covered in
the chapter, leaving the recipes free to show specific techniques.

We definitely want more GUI recipes, but I don't know what techniques
they should illustrate. PDF creation, SQLite integration, XML->YAML
mapping, specific web service integrations, etc. are all great ideas.
I'd like to have a section on system administration tasks, but I'm not
a sysadmin, so I'd like to hear from Ruby-using sysadmins what recipes
they'd like to see or share.

Right now the best way to see whether a recipe in the outline has been
written is to email me and ask about it. I've put up a progress report
on the Cookbook webpage, but it's just a rough indicator. So far we've
written about 75 of the 300 recipes in the outline, and almost all of
them are from chapters 1-8 and 12. That should give you a rough idea.

Leonard
 
G

gabriele renzi

Peter Hickman ha scritto:
Something on SDL perhaps, create your own CD / MP3 player.

this used to work some years ago:
require 'sdl'
SDL.init( SDL::INIT_CDROM )
(Cd=SDL::CD.open(0)).status
def play(trk)
Cd.playTracks(trk,0,0,0)
end
def stop
Cd.stop
end

then irb -r cdplayer and you're done ;)

BTW a better example would be nice, +1 for sdl/rudl/gosu examples
 
R

Rich Morin

Seeing all these ideas go wafting by, I'm struck by the notion that
these cookbook ideas (and the corresponding recipes) would make good
wiki fodder. Wouldn't a Ruby Cookbook wiki be useful and Rubyish?

-r

P.S. I would also want to see O'Reilly do a book, but I imagine that
arrangements could be made to allow this...
 
M

Mike Wilson

We definitely want more GUI recipes, but I don't know what techniques
they should illustrate. PDF creation, SQLite integration, XML->YAML
mapping, specific web service integrations, etc. are all great ideas.
I'd like to have a section on system administration tasks, but I'm not
a sysadmin, so I'd like to hear from Ruby-using sysadmins what recipes
they'd like to see or share.

I'm a sysadmin who uses Ruby :O) How about a logfile reader. Here's
mine, although I'm sure the turd could be polished quite heavily!

------ cut config --------
mailhost: mailhost
tmout: 3600
grab: 1

patterns:
- !ruby/struct:LoganStruct
pattern: "correctable error detected"
grab: 5
email: (e-mail address removed)
post: "-r CRITICAL -m 'Logan(thishost): correctable error detected - Co=
ntac
t Unix Admin Team' hostname=3Dthishost general_use SCRIPTS"

- !ruby/struct:LoganStruct
pattern: "Error Level: Retryable"
except: QUANTUM
grab: 5
email: (e-mail address removed)
post: "-r CRITICAL -m 'Logan(thishost): Retryable disk error detected -=
Con
tact Unix Admin Team' hostname=3Dthishost general_use SCRIPTS"

- !ruby/struct:LoganStruct
pattern: "NFS getattr failed for server"
email: (e-mail address removed)
#post: "-r CRITICAL -m 'Logan(thishost): NFS getattr failed - Contact U=
nix A
dmin Team' hostname=3Dthishost general_use SCRIPTS"

- !ruby/struct:LoganStruct
pattern: "logan.* Config file error"
email: (e-mail address removed)
tmout: 0
------------- end config ---------------

------------- start script ----------------
#!/usr/local/bin/ruby

# @(#)logan=091.4 06/15/05
#
# Program Name: logan
# Date Created: 06/01/05
# Creator: Mike Wilson
#
# SYNOPSIS
# logan [-d] -c config_file -l logfile
#
# DESCRIPTION
# Pattern matches patterns specified in config_file (YAML) against logfi=
le.
#
require "yaml"
require "socket"
require "syslog"
require "net/smtp"
require "file/tail"
require "getoptlong"

$config =3D {}
$progname =3D File.basename($0)
thishost =3D Socket.gethostname
tivenv =3D "/etc/Tivoli/setup_env.sh"
usetiv =3D false
daemon =3D false
logfile =3D nil
config_file =3D nil

opts =3D GetoptLong.new(
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT],
["--daemon", "-d", GetoptLong::NO_ARGUMENT],
["--logfile", "-l", GetoptLong::REQUIRED_ARGUMENT]
)

logan_struct =3D Struct::new("LoganStruct",
:pattern, :tmout, :grab, :except, :mailhost, :email, :post, :expire)


def daemonize()
fork and exit
Process.setsid
fork and exit
File.open("/dev/null", "r+") do |devnull|
$stdin.reopen(devnull)
$stdout.reopen(devnull)
$stderr.reopen(devnull)
end

Dir.chdir("/")
end

def source(file)
response_match =3D Regexp.new(/^([^=3D]*)=3D(.*)/)

`#{ENV['SHELL']} -c ". #{file}; set"`.each_line do |line|
if response_match.match(line)
k, v =3D line.gsub(/^([^=3D]*)=3D(.*)/, '\1 \2').split
ENV[k] =3D v
end
end
end

def logConfigLoadError(config_file)
Syslog.open($progname, Syslog::LOG_PID, Syslog::LOG_DAEMON) do |syslog|
syslog.log(Syslog::LOG_ALERT, "Config file error in #{config_file}"=
)
end
end

def parseYamlConfig(file)
tmpconfig =3D {}
begin
tmpconfig =3D YAML::load(File.open(file))
rescue =3D> err
if $config.size =3D=3D 0
raise err
else
logConfigLoadError(file)
end
else
$config =3D tmpconfig
end

p $config if $DEBUG
$config
end

def convertToRegexp(topat)
pat =3D nil

case topat
when String
pat =3D Regexp.new(topat)
when Regexp
pat =3D topat
end

pat
end

def setDefault(check, master, lastchance)
if not check
if master
check =3D master
else
check =3D lastchance
end
end

check
end

def setDefaultConfigVals(tmout =3D 3600, mailhost =3D "mailhost", grab =3D =
1)
$config["patterns"].each do |pat|
pat.expire =3D 0
pat.pattern =3D convertToRegexp(pat.pattern)
pat.except =3D convertToRegexp(pat.except)
pat.mailhost =3D setDefault(pat.mailhost, $config["mailhost"], mail=
host)
pat.tmout =3D setDefault(pat.tmout, $config["tmout"], tmout)
pat.grab =3D setDefault(pat.grab, $config["grab"], grab)
end
end

def lookForPatternsInLogfile(file)
if File.exists?(file) and File.stat(file).readable?
File::Tail::Logfile.open(file, :rewind=3D>0) do |log|
lines =3D []
pattern =3D nil
grab =3D 0
log.tail do |line|
if grab > 1
lines << line
grab -=3D 1
if grab =3D=3D 1
yield pattern, lines
lines =3D []
end
end

$config["patterns"].each do |pat|
if pat.pattern.match(line)
if pat.grab > 1
lines << line
pattern =3D pat
grab =3D pat.grab
else
yield pat, line
end
end
end
end
end
end
end

def sendMail(email, alert, host, mailhost =3D "mailhost")
message =3D <<EndOfMsg
Subject: Log Analyzer Alert for #{host}
To: #{email}
From: #{$progname.upcase}

The following pattern match was made on #{host} at #{Time.now}

#{alert}

EndOfMsg

Net::SMTP.start(mailhost, 25) do |smtp|
smtp.send_mail(message, '"#{$progname.upcase}"', email)
end
end

def postMessage(msg)
system("postemsg #{msg} > /dev/null 2>&1")
end


opts.each do |opt, arg|
case opt
when "--daemon"
daemon =3D true
when "--logfile"
logfile =3D File.expand_path(arg)
when "--config-file"
config_file =3D File.expand_path(arg)
end
end

if not logfile or not config_file
fail "Usage: #{$progname} [-d] -c config_file -l logfile"
end

hup_proc =3D proc { |*a|
puts "Received signal to reload config"
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
trap("HUP", hup_proc)
}
trap("HUP", hup_proc)
trap("INT") { exit }
trap("TERM") { exit }

parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
daemonize if daemon

if File.exists?(tivenv)
source(tivenv)
usetiv =3D true
end

lookForPatternsInLogfile(logfile) do |pat, msg|
if pat.expire <=3D Time.now.to_i
pat.expire =3D 0
end

if not pat.except or not pat.except.match(msg.to_s)
if pat.expire =3D=3D 0
pat.expire =3D Time.now.to_i + pat.tmout
if pat.email
pat.email.each do |e|
sendMail(e, msg, thishost, pat.mailhost)
end
end

if pat.post
postMessage(pat.post) if usetiv
end

puts msg
end
end
end
------------------ end script ------------
 
E

ES

Peter said:
Well we could start with a couple of chapters for ideas

Databases
Using dbi to access your database
Quick and easy databases with sqlite
Using activerecord

Or maybe introduce KirbyBase with a caveat "unless you really
need a RDBMS". Also, some of the other ORMs (Og, Kansas) are
interesting.
XML
Creating XML documents
Processing XML with REXML

How about starting with "YAML. Seriously. YAML." and then, if
the user really wants to mess with XML, show off REXML and XML::Builder.
Net
Automating web access with net/http
Using SSL for secure web access
Using Webrick
Using the Flickr API

Websites
Custom cgi scripts
Page templating for automatic site building
Forms processing

Basically we just need to think of things in terms of a user asking "How
do I ..."

This is definitely true!
Just think of things that you can do with Ruby that other people will
also want to do.

E
 
G

Gavin Sinclair

Rich said:
Seeing all these ideas go wafting by, I'm struck by the notion that
these cookbook ideas (and the corresponding recipes) would make good
wiki fodder. Wouldn't a Ruby Cookbook wiki be useful and Rubyish?

Yes, but it's a _lot_ of effort. At least three people have tried to
create/organise online Ruby cookbooks in the past, yet we're still
having this discussion :)

Some things just require the intense focus of a book author.

Gavin
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top