[#154598] implementing the "each" method for own classes — Philipp Huber <huber.philipp@...>

hello!

12 messages 2005/09/01

[#154620] Word Chains (#44) — Ruby Quiz <james@...>

Gavin Kistner asked that I try timing the quiz solutions this week. I did

13 messages 2005/09/01

[#154733] Ruby-specific performance heuristics? — Hugh Sasse <hgs@...>

I've been doing some stuff with CSV recently, having data in one

15 messages 2005/09/02

[#154775] Idiomatic conversion of yielding block to array — David Brady <ruby_talk@...>

So I have a function that generates like 300 lines of text and I want to

23 messages 2005/09/02
[#154776] Re: Idiomatic conversion of yielding block to array — Levin Alexander <levin.alexander@...> 2005/09/02

David Brady <ruby_talk@shinybit.com> wrote:

[#154779] Re: Idiomatic conversion of yielding block to array — Simon Krer <SimonKroeger@...> 2005/09/02

Levin Alexander wrote:

[#154785] Re: Idiomatic conversion of yielding block to array — Simon Krer <SimonKroeger@...> 2005/09/02

Simon Krer wrote:

[#154789] Re: Idiomatic conversion of yielding block to array — Jacob Fugal <lukfugl@...> 2005/09/02

Good heavens, no! Neither of those are thread safe. Criminy!

[#154872] windows shell — Gaston Garcia <gaston.garcia@...>

Is there anyone here that uses Windows XP and uses a windows shell

28 messages 2005/09/04
[#154876] Re: windows shell — "Robert Klemme" <bob.news@...> 2005/09/04

Gaston Garcia <gaston.garcia@gmail.com> wrote:

[#154917] Re: windows shell — Austin Ziegler <halostatue@...> 2005/09/05

On 9/4/05, Robert Klemme <bob.news@gmx.net> wrote:

[#154874] params v.s. @params in rails? — "Barry" <rubyrails@...>

Both work in my controller class, so I am wondering what's the

11 messages 2005/09/04

[#154920] Help me clean up this method — "Vincent Foley" <vfoley@...>

Hello guys,

32 messages 2005/09/05

[#155018] Rake 0.6.0 Released — Jim Weirich <jim@...>

= Rake 0.6.0 Released

20 messages 2005/09/06

[#155064] Sorted arrays — <ruby@...64.com>

I'm a relative newcomer to Ruby. Most of my experience is in Delphi. And in Delphi one of the most commonly-used classes is TStringList, which is sort of analogous to ruby's Array (Delphi also has dynamic arrays and static arrays). TStringList has a property called Sorted, which if set to True makes it possible to insert strings into the list and have it maintain them as a sorted list (without having to re-sort it each time). Then you can use the IndexOf method (or the Find method) to do a binary search on the list, so you can quickly find the element you're looking for. My question is whether Ruby has anything like this. It seems like one could create a descendant of Array that does this.

18 messages 2005/09/06
[#155067] Re: Sorted arrays — "Robert Klemme" <bob.news@...> 2005/09/06

ruby@danb64.com wrote:

[#155120] Units for Ruby — "Lucas Carlson" <lucas@...>

I have also created a new library to add units to numbers in Ruby:

14 messages 2005/09/06

[#155127] Rio 0.3.4 — "rio4ruby" <rio4ruby@...>

New and Improved -- Rio 0.3.4

24 messages 2005/09/07

[#155181] Need help finding decent IDE/development environment for Windows — "Paul Dix" <paulcdix@...>

I've just started playing around with ruby on rails and by association,

41 messages 2005/09/07
[#155218] Re: Need help finding decent IDE/development environment for Windows — graham <fghfghfh@...> 2005/09/07

Paul Dix wrote:

[#155220] Re: Need help finding decent IDE/development environment for Windows — Joe Van Dyk <joevandyk@...> 2005/09/07

On 9/7/05, graham <fghfghfh@homr.vom> wrote:

[#155221] Re: Need help finding decent IDE/development environment for Windows — graham <fghfghfh@...> 2005/09/07

> You could ask them why they need all that IDE stuff for developing in Ruby.

[#155225] Re: Need help finding decent IDE/development environment for Windows — Edward Faulkner <ef@...> 2005/09/07

On Thu, Sep 08, 2005 at 02:36:29AM +0900, graham wrote:

[#155264] Re: Need help finding decent IDE/development environment for Windows — graham <fghfghfh@...> 2005/09/07

Edward Faulkner wrote:

[#155280] Re: Need help finding decent IDE/development environment for Windows — James Edward Gray II <james@...> 2005/09/08

On Sep 7, 2005, at 6:56 PM, graham wrote:

[#155327] general performance question — Brian Le Roy <brian@...>

I'm running top and when I run my app - I see the user CPU utilitization

15 messages 2005/09/08

[#155364] KirbyBase — rubyhacker@...

I'm posting from work, but will try to follow up in more

57 messages 2005/09/08
[#155795] Re: KirbyBase — rubyhacker@... 2005/09/12

Jamey Cribbs wrote:

[#155801] Re: KirbyBase — Jamey Cribbs <cribbsj@...> 2005/09/12

rubyhacker@gmail.com wrote:

[#155818] Re: KirbyBase — Randy Kramer <rhkramer@...> 2005/09/12

On Monday 12 September 2005 04:11 pm, Jamey Cribbs wrote:

[#155833] Re: KirbyBase — rubyhacker@... 2005/09/12

Randy Kramer wrote:

[#155836] Re: KirbyBase — Kevin Brown <blargity@...> 2005/09/12

On Monday 12 September 2005 17:06, rubyhacker@gmail.com wrote:

[#155861] Re: KirbyBase — Hal Fulton <hal9000@...> 2005/09/13

Kevin Brown wrote:

[#155873] Re: KirbyBase — Ezra Zygmuntowicz <ezra@...> 2005/09/13

[#155976] Re: KirbyBase — rubyhacker@... 2005/09/13

[#155986] Re: KirbyBase — Jamey Cribbs <cribbsj@...> 2005/09/13

rubyhacker@gmail.com wrote:

[#156005] Re: KirbyBase — Logan Capaldo <logancapaldo@...> 2005/09/13

[#156029] Re: KirbyBase [ANN (sort-of)] proof-of-concept KirbyBase ORM — Logan Capaldo <logancapaldo@...> 2005/09/14

[#155369] compiling ruby on red hat linux — "Philip J. Mikal" <philip_mikal@...>

Hi,

15 messages 2005/09/08

[#155411] Optimizing a single slow method — "Glenn M. Lewis" <noSpam@...>

Hi!

34 messages 2005/09/09
[#155474] Re: Optimizing a single slow method — Eric Hodel <drbrain@...7.net> 2005/09/09

On 08 Sep 2005, at 20:46, Glenn M. Lewis wrote:

[#155464] quick print type debugging — Eric Mahurin <eric_mahurin@...>

Anybody think something like this would be useful?

12 messages 2005/09/09

[#155507] Using Ruby as a preprocessor for another language — debbie@...

I have the misfortune of being stuck programming in a very bad

11 messages 2005/09/10

[#155530] Win32 gem for RMagick 1.9.1 — Timothy Hunter <cyclists@...>

Hot on the heels of the latest RMagick update, Kaspar Schiess has

15 messages 2005/09/10

[#155537] RCR to modify #puts and #print inside ERB — Gavin Kistner <gavin@...>

Proposed RCR:

26 messages 2005/09/10

[#155601] r4 - the simplest ruby pre-processor — "Ara.T.Howard" <Ara.T.Howard@...>

18 messages 2005/09/11

[#155638] The Early Demise of Myriad (Thanks To Ruby Threads) — "Zed A. Shaw" <zedshaw@...>

Hi Everyone,

17 messages 2005/09/11

[#155708] how to well-qualify the 2-inherited methods at their collision point — "SHIGETOMI, Takuhiko" <tshiget1@...>

dear guys,

10 messages 2005/09/12

[#155828] Adventures in html decoding. — Morgan <taria@...>

From the "If you want it done right, do it yourself... maybe"

16 messages 2005/09/12

[#155847] Choosing an open source license — "debbie@..." <debbie@...>

I'm working on a server program and I'm trying to decide which open

22 messages 2005/09/13

[#155941] yet another simple command-line option parser — Eric Mahurin <eric_mahurin@...>

I just put in a good example for:

11 messages 2005/09/13
[#155946] Re: yet another simple command-line option parser — Jim Freeze <jim@...> 2005/09/13

That's pretty interesting Eric, to grab the type off the default.

[#155949] Sets, uniqueness not unique. — Hugh Sasse <hgs@...>

I have been splitting a comma separated values file, and putting

29 messages 2005/09/13

[#155970] Surprising Regexp Behavior — James Edward Gray II <james@...>

I keep running into some surprising points with Ruby's Regexp engine

13 messages 2005/09/13

[#155992] Launch directory in Rake — Jim Freeze <jim@...>

Hi

15 messages 2005/09/13

[#156053] ruby and aop — Alexandru Popescu <the.mindstorm.mailinglist@...>

Hi!

12 messages 2005/09/14

[#156189] Get to the Point: Ruby and Rails Presentation Slides — "John W. Long" <ng@...>

Hi,

20 messages 2005/09/15

[#156230] you can't get in trouble with your boss for picking C# — "Phlip" <phlipcpp@...>

Rubies:

69 messages 2005/09/15
[#156549] Re: you can't get in trouble with your boss for picking C# — "ToRA" <tristan.allwood@...> 2005/09/17

Hey all,

[#156582] Re: you can't get in trouble with your boss for picking C# — Florian Gro<florgro@...> 2005/09/18

ToRA wrote:

[#156297] Re: you can't get in trouble with your boss for picking C# — "Phlip" <phlipcpp@...> 2005/09/15

klancaster1957 wrote:

[#156308] Re: you can't get in trouble with your boss for picking C# — Josh Charles <josh.charles@...> 2005/09/15

On 9/15/05, Phlip <phlipcpp@yahoo.com> wrote:

[#156248] Math: sum and faculty — Daniel Schierbeck <daniel.schierbeck@...>

I hereby propose two additions to Ruby. Please come with some comments

13 messages 2005/09/15

[#156299] MS Access — "Steve" <sdouglas949@...>

I'm considering learning Ruby. I have no programming experience yet. I was

23 messages 2005/09/15
[#156303] Re: MS Access — "Phlip" <phlipcpp@...> 2005/09/15

Steve wrote:

[#156335] Re: MS Access — Sean Armstrong <phinsxiii@...> 2005/09/15

On 9/15/05, Phlip <phlipcpp@yahoo.com> wrote:

[#156336] Re: MS Access — Sascha Ebach <se@...> 2005/09/15

Sean Armstrong wrote:

[#156347] Re: MS Access — Sean Armstrong <phinsxiii@...> 2005/09/15

Does anyone know how to install the Ruby MySQL module on a Windows platform.

[#156352] Re: MS Access — Jacob Quinn Shenker <jqshenker@...> 2005/09/15

Sean,I needed to compile/install mysql (running ./configure--without-server) from source to get the required developmentlibraries under Cygwin. (then I moved the newly-created clientbinaries out of the way so I could use the Win32-native mysqlbinaries.) After that, it worked like a charm. *Do not compile theCygwin-ized mysql client with "--with-openssl"* I don't know why, butthe gem refused to install if I did. Good luck, and let me know if yourun into any issues. Overall, developing on Cygwin for Ruby/Rails isquite nice.

[#156353] Re: MS Access — Sean Armstrong <phinsxiii@...> 2005/09/15

Let me make sure I got this right:

[#156461] Re: MS Access — Sean Armstrong <phinsxiii@...> 2005/09/16

It still refuses to find the lib and include directories even if I use the

[#156506] Re: MS Access — Jacob Quinn Shenker <jqshenker@...> 2005/09/16

Sean,I'm going to try to explain *exactly* what I did, and hopefully you'llsee something you forgot to do.1. Download mysql-essential-4.1.14-win32.msi from mysql.org and install it.2. Download mysql-4.1.13.tar.gz from mysql.org3. Extract the above, and run "./configure -C --without-server" (the-C enables config caching, I use it because the ./configure scriptruns very slowly under Cygwin. Optional, of course)4. Run "make && make install"5. Run "gem install mysql"6. Go make cool rails apps!

[#156444] Hash table questions — EdUarDo <eduardo.yanezNOSPAM@...>

Hi all,

14 messages 2005/09/16

[#156480] Some interesting criticisms of rails — David Balick <davidbalick@...>

may be found in the podcast

24 messages 2005/09/16
[#156530] Re: Some interesting criticisms of rails — "Robert Klemme" <bob.news@...> 2005/09/17

Zed A. Shaw <zedshaw@zedshaw.com> wrote:

[#156624] Language recommendations from ruby persons.... — "Greg Lorriman" <bogus@...>

Dear sirs and madames,

36 messages 2005/09/18

[#156662] Capcha in ruby — Federico <pix@...>

Hello,

23 messages 2005/09/19

[#156708] help with tricky proc/binding issue — "Ara.T.Howard" <Ara.T.Howard@...>

14 messages 2005/09/19

[#156743] The Ruby troll [was: Looking for...] — Gunnar Hjalmarsson <noreply@...>

David H. Adler wrote:

22 messages 2005/09/19

[#156749] ruby idiom for python's for/else while/else — Gergely Kontra <kgergely@...>

Hi!

18 messages 2005/09/19

[#156796] Dissident 0.1, a Ruby dependency injection container — Christian Neukirchen <chneukirchen@...>

Hello,

13 messages 2005/09/20
[#156797] Re: [ANN] Dissident 0.1, a Ruby dependency injection container — "Jason Voegele" <jason@...> 2005/09/20

On Tue, September 20, 2005 8:22 am, Christian Neukirchen said:

[#156801] Re: [ANN] Dissident 0.1, a Ruby dependency injection container — Christian Neukirchen <chneukirchen@...> 2005/09/20

"Jason Voegele" <jason@jvoegele.com> writes:

[#156966] Re: [ANN] Dissident 0.1, a Ruby dependency injection container — Logan Capaldo <logancapaldo@...> 2005/09/21

This is a little OT, but every-time dependency injection comes up I

[#156866] Places for a programmer to live? — Devin Mullins <twifkak@...>

While we seem to be rife with OT threads, I thought I'd throw in an OT

37 messages 2005/09/20

[#156933] Hello, I am a newbie to ruby. — could ildg <could.net@...>

I want learn a script language.

11 messages 2005/09/21

[#157005] Large Ruby Apps ? — "Warren Seltzer" <warrens@...>

I am coming to Ruby having used the usual list of scripting and C* languages. Since Ruby

30 messages 2005/09/21
[#158399] Re: Large Ruby Apps ? — <slonik.az@...> 2005/09/30

Very useful discussion that highlights quite few misconceptions.

[#157007] Re: Large Ruby Apps ? — "Berger, Daniel" <Daniel.Berger@...>

> -----Original Message-----

27 messages 2005/09/21

[#157051] hi, i'm new. plus one question — travis laduke <wrong@...>

I've been forced to work on some php lately and found myself

13 messages 2005/09/22

[#157063] Visual IDEs?? — "Erland" <Erland.Erikson@...>

HI,

24 messages 2005/09/22

[#157080] A question about Intelligent Systems and using Ruby — Daniel Lewis <danieljohnlewis@...>

Yesterday (21/09/2005) I sent an email to Dave Thomas (author of

16 messages 2005/09/22

[#157101] Instantiating a subclass of NilClass. — "Trans" <transfire@...>

I've subclasses NilClass, but don't know how to instantiate it. Any

16 messages 2005/09/22

[#157189] "The class that it is mixed in to..." — John Carter <john.carter@...>

Ok, so I'm documenting a Mixin.

20 messages 2005/09/23
[#157193] Re: "The class that it is mixed in to..." — William Morgan <wmorgan-ruby-talk@...> 2005/09/23

Excerpts from John Carter's mail of 22 Sep 2005 (CDT):

[#157271] Re: "The class that it is mixed in to..." — "David A. Black" <dblack@...> 2005/09/23

Hi --

[#157222] RDE 1.0.0 released — sakazuki <qzs01353@...>

Hi.

16 messages 2005/09/23

[#157299] On accidental unsubscribe messages — "Berger, Daniel" <Daniel.Berger@...>

Hi all,

15 messages 2005/09/23

[#157520] Relative speed of Ruby vs Java for a large compiled app like Freenet — seekingleverage@...

I'm wondering if anyone could shed some light on whether or not it

45 messages 2005/09/25
[#157716] Re: Relative speed of Ruby vs Java for a large compiled app like Freenet — "Isaac Gouy" <igouy@...> 2005/09/26

Martin, perhaps you could collect this stuff and put it into your wiki

[#157540] String#ggsub — Gavin Kistner <gavin@...>

I occasionally find myself with gsub regexp that either eat too much,

21 messages 2005/09/25

[#157565] Rinda frustration — Mark Volkmann <r.mark.volkmann@...>

I'm trying to determine what the methods "move" and "notify" do in the

12 messages 2005/09/26

[#157623] A big thank you to Robby Russell... — Tom Copeland <tom@...>

...for providing another RubyForge mirror via his company, PlanetArgon.

18 messages 2005/09/26
[#157770] Re: A big thank you to Robby Russell... — Gavin Kistner <gavin@...> 2005/09/27

On Sep 26, 2005, at 7:25 AM, Tom Copeland wrote:

[#157826] Re: A big thank you to Robby Russell... — Tom Copeland <tom@...> 2005/09/27

On Tue, 2005-09-27 at 12:43 +0900, Gavin Kistner wrote:

[#157864] Re: A big thank you to Robby Russell... — Sam Mayes <codeslave@...> 2005/09/27

whats the process for becomming a mirror?

[#157871] Re: A big thank you to Robby Russell... — Kirk Haines <khaines@...> 2005/09/27

On Tuesday 27 September 2005 10:24 am, Sam Mayes wrote:

[#157875] Re: A big thank you to Robby Russell... — Tom Copeland <tom@...> 2005/09/27

On Wed, 2005-09-28 at 01:38 +0900, Kirk Haines wrote:

[#157648] Rapid GUI Development with QtRuby — Dave Thomas <dave@...>

I hope y'all don't mind a short announcement, but it seemed relevant.

22 messages 2005/09/26

[#157654] Ruby Threads 101 — Ben <benbelly@...>

I am leading a peer-learning group that is using "Programming Ruby" to

13 messages 2005/09/26

[#157658] Time interval — Daniel Berger <Daniel.Berger@...>

Hi all,

20 messages 2005/09/26

[#157697] Embedded Ruby and Tag Libs — Adam Van Den Hoven <mail@...>

Hey guys,

16 messages 2005/09/26

[#157732] ShortURL 0.7.0 — "Vincent Foley" <vfoley@...>

After a lot of procrastination, I have released ShortURL 0.7.0. I

14 messages 2005/09/26

[#157746] Fwd: Lisp macros — Joe Van Dyk <joevandyk@...>

Whoops, this belongs on ruby-talk... Sorry.

47 messages 2005/09/27
[#157751] Re: Fwd: Lisp macros — James Britt <james_b@...> 2005/09/27

Joe Van Dyk wrote:

[#157779] Re: Fwd: Lisp macros — Jim Freeze <jim@...> 2005/09/27

On 9/26/05, James Britt <james_b@neurogami.com> wrote:

[#157813] Re: Fwd: Lisp macros — Ben <benbelly@...> 2005/09/27

On 9/27/05, Jim Freeze <jim@freeze.org> wrote:

[#157807] How do I (really) encrypt a string in ruby? — Michal Suchanek <hramrach@...>

Hello

10 messages 2005/09/27

[#157854] Class and Iterator Design Question — Jim Freeze <jim@...>

This may be a silly design question, but I always balk at

26 messages 2005/09/27
[#157866] Re: Class and Iterator Design Question — Bob Hutchison <hutch@...> 2005/09/27

[#157889] Re: Class and Iterator Design Question — Jim Freeze <jim@...> 2005/09/27

Wow, thanks for all the responses.

[#157893] Re: Class and Iterator Design Question — "David A. Black" <dblack@...> 2005/09/27

Hi --

[#157896] Re: Class and Iterator Design Question — Jim Freeze <jim@...> 2005/09/27

On 9/27/05, David A. Black <dblack@wobblini.net> wrote:

[#157947] Dynamically generating classes? — Jonas Galvez <jonasgalvez@...>

Hi,

15 messages 2005/09/27

[#158051] Re: creating independent lambdas in loops — "Kroeger Simon (ext)" <simon.kroeger.ext@...>

24 messages 2005/09/28
[#158057] Re: creating independent lambdas in loops — Eric Mahurin <eric_mahurin@...> 2005/09/28

--- "Kroeger Simon (ext)" <simon.kroeger.ext@siemens.com>

[#158074] Re: creating independent lambdas in loops — Gavin Kistner <gavin@...> 2005/09/28

On Sep 28, 2005, at 7:47 AM, Eric Mahurin wrote:

[#158081] Re: creating independent lambdas in loops — Eric Mahurin <eric_mahurin@...> 2005/09/28

--- Gavin Kistner <gavin@refinery.com> wrote:

[#158093] Re: creating independent lambdas in loops — Eric Mahurin <eric_mahurin@...> 2005/09/28

--- Eric Mahurin <eric_mahurin@yahoo.com> wrote:

[#158094] Re: creating independent lambdas in loops — "David A. Black" <dblack@...> 2005/09/28

Hi --

[#158096] Re: creating independent lambdas in loops — Eric Mahurin <eric_mahurin@...> 2005/09/28

--- "David A. Black" <dblack@wobblini.net> wrote:

[#158121] Python to Ruby: Two puzzlements... — "Elf M. Sternberg" <elf@...>

I'm afraid that I'm coming from Python, a B&D language where I'm used to

22 messages 2005/09/28

[#158157] IBM vs. Microsoft vs. ... Ruby? — "itsme213" <itsme213@...>

More "Enterprise Scale" talk over here, with a strong leaning towards

29 messages 2005/09/28
[#158330] Re: IBM vs. Microsoft vs. ... Ruby? — "bonefry" <bellarchitects@...> 2005/09/29

Hi,

[#158258] In your opinion.... — Daniel Lewis <danieljohnlewis@...>

In your opinion(s)....

51 messages 2005/09/29
[#158263] Re: In your opinion.... — Gennady Bystritksy <gfb@...> 2005/09/29

Daniel Lewis wrote:

[#158265] Re: In your opinion.... — Daniel Lewis <danieljohnlewis@...> 2005/09/29

> Too lazy to do your own research? It happens ;-). For a starter, check

[#158311] rush 0.1.bandicoot: object-oriented shell goodness (rationed for your health)! — The rush folks <rush-ruby-ml@...>

= rush-0.1.bandicoot

10 messages 2005/09/29

[#158327] Operator Overloading << — "matt.hulse@..." <matt.hulse@...>

Is there a way to overload '<<' in the Array class?

19 messages 2005/09/29

[#158460] Ruby licence... — netspam@...

I understand that the distribution of Ruby is under the GPL.

25 messages 2005/09/30
[#158600] Re: Ruby licence... — "Gregory Brown" <gregory.t.brown@...> 2005/10/02

The Ruby License and the License of Ruby are two different things.

[#158620] Re: Ruby licence... — Kevin Brown <blargity@...> 2005/10/02

On Saturday 01 October 2005 20:51, Gregory Brown wrote:

[#158659] Re: Ruby licence... — Christian Neukirchen <chneukirchen@...> 2005/10/02

Kevin Brown <blargity@gmail.com> writes:

[#158663] Re: Ruby licence... — Kevin Brown <blargity@...> 2005/10/02

On Sunday 02 October 2005 10:56, Christian Neukirchen wrote:

[#158690] Re: Ruby licence... — Christian Neukirchen <chneukirchen@...> 2005/10/02

Kevin Brown <blargity@gmail.com> writes:

[#158692] Re: Ruby licence... — Kevin Brown <blargity@...> 2005/10/02

On Sunday 02 October 2005 12:45, Christian Neukirchen wrote:

[#158497] Interest in Boost::Ruby — Alan Gutierrez <alan-ruby-talk@...>

I'd like to build a CSS renderer in modern C++ as an enthusist's

24 messages 2005/09/30

[SUMMARY] Math Captcha (#48)

From: Ruby Quiz <james@...>
Date: 2005-09-29 12:34:05 UTC
List: ruby-talk #158230
It's always great running the Ruby Quiz, because I quite literally learn
something new every single week.  This week's big lesson:  Steal Glenn Parker's 
code, whenever possible!

Both Gavin and I "borrowed" Glenn's solution to Ruby Quiz #25 to help us convert
digits to English words.  Thanks Glenn, you made us both look good.

I'm going to show my solution below, mostly because it's shorter and I'm pretty
lazy.  However, Gavin's code had some interesting things in it you really
shouldn't miss.  So I'll talk about my favorite feature in that code a little
first.

I wasn't too keen on the extra credit idea of difficultly, because it sounded a
little too subjective to me.  Neither Gavin or I really did that part, but Gavin
did add categorization for the questions and I have to tell you that is one cool
feature, both in idea and implementation.  Here's an explanation of how it
works, from the author:

	I created a framework where you categorize types of captchas in an
	hierarchy, and you can ask for a specific type of captcha by using the
	desired subclass.
	
	For example, in my code below, I have:

	class Captcha::Zoology < Captcha ... end
	class Captcha::Math < Captcha
	   class Basic < Math ... end
	   class Algebra < Math ... end
	end

	This allows you to do:

	Captcha.create_question # a question from any framework, while
	Captcha::Zoology.create_question # only questions in this class
	Captcha::Math.create_question # any question in Math or its subclasses
	Captcha::Math::Basic.create_question # only Basic math questions

Sounds clever, right?  I was far more impressed when I looked under the hood to
find out how it is done.  It's really just a few simple methods doing the work:

	class Captcha
	  # ...
	
	  # Returns a hash with two values:
	  # _question_:: A string with the question that the user should answer
	  # _answer_id_:: A unique ID for this question that should be passed to
	  #               #check_answer or #get_answers
	  def self.create_question
	    question, answers = factories.random.call
	    answer_id = AnswerStore.instance.store( answers )
	    return { :question => question, :answer_id => answer_id }
	  end
	
	  # ...
	
	  # Add the block to my store of question factories
	  def self.add_factory( &block )
	    ( @factories ||= [] ) << block
	  end
	
	  # Keep track of the classes that inherit from me
	  def self.inherited( subklass )
	    ( @subclasses ||= [] ) << subklass
	  end
	
	  # All the question factories in myself and subclasses
	  def self.factories
	    @factories ||= []
	    @subclasses ||= []
	    @factories + @subclasses.map{ |sub| sub.factories }.flatten
	  end
	
	  # ...
	end

First notice the self.inherited() class method.  That's a hook Ruby calls
whenever your class is subclassed.  This method just tracks all known
subclasses, as you can see.

The self.add_factory() method is used by subclasses to add "question factories"
for the topic that class represents.  Again, these are just collected into an
Array.

The real magic is self.factories(), though it too is trivial.  When asked to
return its factories, it returns its own and all the factories for subclasses. 
All of that comes together in one more interface method.

When user code asks for a question with self.create_question(), a call to
self.factories() ensures that anything added by self.add_factory() can be
selected in addition to any factories of known subclasses tracked by
self.inherited().

I just think that's too smooth.  Thanks for the lesson, Gavin!

Alright, let's examine a complete example solution.  Here's the start of my
code:

	#!/usr/local/bin/ruby -w
	
	require "erb"
	
	# Glenn Parker's code from Ruby Quiz 25...
	require "english_numerals"
	class Integer
		alias_method :to_en, :to_english
	end
	
	class Array
		def insert_at_nil( obj )
			if i = index(nil)
				self[i] = obj
				i
			else
				self << obj
				size - 1
			end
		end
	end
	
	# ...

Just a little setup work here.  I pull in ERb for question templates, load
Glenn's Ruby Quiz #25 solution and add a shortcut to it, and finally add a
method to Array for inserting an object at the first nil position and returning
the index of where it ended up.

Now we get to some captcha code:

	# ...
	
	module MathCaptcha
		@@captchas = Array.new
		@@answers  = Array.new
		
		def self.add_captcha( template, &validator )
			@@captchas << Array[template, validator]
		end
		
		def self.create_question
			raise "No captchas loaded." if @@captchas.empty?
			
			captcha = @@captchas[rand(@@captchas.size)]
			
			args = Array.new
			class << args
				def arg( value )
					push(value)
					value
				end
				
				def resolve( template )
					ERB.new(template).result(binding)
				end
			end
			question = args.resolve(captcha.first)
			index    = @@answers.insert_at_nil(Array[captcha.first, *args])
			
			Hash[:question  => question, :answer_id => index]
		end
		
		# ...

The first method, self.add_captchas(), is my answer to the first extra credit. 
My code reads a configuration file in which you can call this method as much as
you want to prepare your captcha system.  You pass in two things:  An ERb
template of the question and a block that will validate answers.

Your template can embed whatever code is needed to produce a question.  Inside
the template you have access to the magic arg() method, which returns whatever
object is passed in, but ensures that that object will also be passed to the
validation block along with the answer.  The point is that you can randomize
whatever you like, and ensure that you have the pieces to validate answers for
the resulting questions when the time comes.

The block is passed the answer given and everything that was filtered through
arg().  It is expected to return true or false, indicating if the answer is
acceptable.

The other method, self.create_question(), is what resolves the ERb template and
tucks the answer details away for later use.  First, one of the added captchas
is selected at random.  That template is then resolved in the context of a
modified Array, with the previously mentioned arg() method.  The template and
Array of arguments are then stored in the @@answers variable for later
validation.  (We can't store the validator because it's a Proc and I serialize
the answers.)  Finally, the question and answer id are returned.

Here's the other half of the module:

		# ...
		
		def self.check_answer( answer )
			raise "Answer id required." unless answer.include? :answer_id
			
			template, *args = @@answers[answer[:answer_id]]
			raise "Answer not found." if template.nil?
			
			validator = @@captchas.assoc(template).last
			raise "Unable to match captcha." if validator.nil?
			
			if validator[answer[:answer], *args]
				@@answers[answer[:answer_id]] = nil
				true
			else
				false
			end
		end
		
		def self.load_answers( file )
			@@answers = File.open(file) { |answers| Marshal.load(answers) }
		end
		
		def self.load_captchas( file )
			code = File.read(file)
			eval(code, binding)
		end
		
		def self.save_answers( file )
			File.open(file, "w") { |answers| Marshal.dump(@@answers, answers) }
		end
	end
	
	# ...

The other side of the equation is self.check_answer(), which uses the provided
id to look up the answer details.  The template from those is used to fetch the
validation block for that question and the block is called.  If the answer
validates, we clear that answer out and return true.  The answer isn't cleared
in the event of a false response, in case a typo was made.

The other three methods are for loading and saving the data the program relies
on.  Answers are serialized and read with the help of Marshal.  The captcha file
is simply eval()ed in the context of the module, so it can add captchas using
Ruby code.

Here's the interface code:

	# ...
	
	if __FILE__ == $0
		captchas = File.join(ENV["HOME"], ".math_captchas")
		unless File.exists? captchas
			File.open(captchas, "w") { |file| file << DATA.read }
		end
		MathCaptcha.load_captchas(captchas)
		
		answers = File.join(ENV["HOME"], ".math_captcha_answers")
		MathCaptcha.load_answers(answers) if File.exists? answers
		
		END { MathCaptcha.save_answers(answers) }
		
		if ARGV.empty?
			question = MathCaptcha.create_question
			puts "#{question[:answer_id]} : #{question[:question]}"
		else
			args = Hash.new
			while ARGV.size >= 2 and ARGV.first =~ /^--\w+$/
				key       = ARGV.shift[2..-1].to_sym
				value     = ARGV.first =~ /^\d+$/ ? ARGV.shift.to_i : ARGV.shift
				args[key] = value
			end
			
			answer = MathCaptcha.check_answer(args)
			puts answer
			
			exit(answer ? 0 : -1)
		end
	end
	
	# ...

The first part of that code reads the captcha and answer files into memory.  If
the captcha file didn't exist, a sample file is created for the user to modify. 
Once the answer file is loaded, an END { ... } block is registered so the
program will be sure to update it on exit.

Finally, we've come to the quiz interface.  If no arguments were given, create a
question.  If we got arguments, check the answer for the indicated question and
print true or false.  I also use the exit code to notify success or failure.

I used the DATA section of the source to store the sample captcha file:

	# ...
	
	__END__
	add_captcha(
		"<%= arg(rand(10)).to_en.capitalize %> plus <%= arg(2).to_en %>?"
	) do |answer, *opers|
		if answer.is_a?(String) and answer =~ /^\d+$/
			answer = answer.to_i.to_en
		elsif answer.is_a?(Integer)
			answer = answer.to_en
		end
		answer == opers.inject { |sum, var| sum + var }.to_en
	end

There's only one example there, but it does show how to use arg() and to_en(). 
The block only looks so complicated because I allow three different forms for
the answer.  I think these templates are pretty flexible, since you get to use
Ruby at both ends to build questions and check answers.

My thanks to Gavin Kistner for a great problem and a clever solution.

Tomorrow's challenge is for all you language junkies out there.  Bring your
translation skills...

In This Thread

Prev Next