[#372953] Strange whitespace parsing behavior on Ruby 1.8.7 (patchlevel 249/302) — Ehsanul Hoque <ehsanul_g3@...>

13 messages 2010/11/02
[#372956] Re: Strange whitespace parsing behavior on Ruby 1.8.7 (patchlevel 249/302) — Robert Klemme <shortcutter@...> 2010/11/02

On Tue, Nov 2, 2010 at 5:49 AM, Ehsanul Hoque <ehsanul_g3@hotmail.com> wrot=

[#372978] Re: Strange whitespace parsing behavior on Ruby 1.8.7 (patchlevel 249/302) — Ehsanul Hoque <ehsanul_g3@...> 2010/11/02

[#373013] Regular Expression — Dv Dasari <dv.mymail@...>

I am trying to write a reqular expression to match a word with my input

22 messages 2010/11/02
[#373016] Re: Regular Expression — Richard Conroy <richard.conroy@...> 2010/11/02

On Tue, Nov 2, 2010 at 9:05 PM, Dv Dasari <dv.mymail@gmail.com> wrote:

[#373018] Re: Regular Expression — Kendall Gifford <zettabyte@...> 2010/11/02

On Tue, Nov 2, 2010 at 3:34 PM, Richard Conroy <richard.conroy@gmail.com> wrote:

[#373049] UTF-8 aware chop for 1.8? — Ammar Ali <ammarabuali@...>

Hello,

12 messages 2010/11/03

[#373070] Ruby Perofrmance — Ruby Me <i_baseet@...>

Hi

21 messages 2010/11/03

[#373097] Ruby vs PHP for the web — Ruby Me <i_baseet@...>

Hi

43 messages 2010/11/04
[#373461] Re: Ruby vs PHP for the web — Charles Calvert <cbciv@...> 2010/11/10

On Wed, 3 Nov 2010 20:49:22 -0500, Ruby Me <i_baseet@hotmail.com>

[#373534] Re: Ruby vs PHP for the web — Mike Stephens <rubfor@...> 2010/11/11

Charles Calvert wrote in post #960599:

[#373563] Re: Ruby vs PHP for the web — Jes俍 Gabriel y Gal疣 <jgabrielygalan@...> 2010/11/12

On Thu, Nov 11, 2010 at 11:50 PM, Mike Stephens <rubfor@recitel.net> wrote:

[#373585] Re: Ruby vs PHP for the web — Josh Cheek <josh.cheek@...> 2010/11/12

2010/11/12 Jes=FAs Gabriel y Gal=E1n <jgabrielygalan@gmail.com>

[#373220] Create a class - ideas — flebber <flebber.crue@...>

15 messages 2010/11/06

[#373248] Code in a class but not in a method -- please explain! — "Bruce F." <brucedfeist@...>

I'm a newcomer to Ruby, and I'm confused about what executable

10 messages 2010/11/07

[#373260] sort_by is not stable ? — Michel Demazure <michel@...>

sort_by is not a stable sorting method (ruby 1.9.2 p0)

22 messages 2010/11/07
[#373262] Re: sort_by is not stable ? — Ammar Ali <ammarabuali@...> 2010/11/07

On Sun, Nov 7, 2010 at 12:22 PM, Michel Demazure <michel@demazure.com> wrot=

[#373264] Re: sort_by is not stable ? — Michel Demazure <michel@...> 2010/11/07

Ammar Ali wrote in post #959889:

[#373265] Re: sort_by is not stable ? — Ammar Ali <ammarabuali@...> 2010/11/07

On Sun, Nov 7, 2010 at 1:15 PM, Michel Demazure <michel@demazure.com> wrote:

[#373266] irb misbehaviour with arrow keys on Windows — Marvin Gülker <sutniuq@...>

Hi there,

10 messages 2010/11/07

[#373352] ruby-pg gem fails to install — Rajinder Yadav <devguy.ca@...>

i built postgres 9.0 from source and i am trying to install ruby-pg

11 messages 2010/11/08

[#373397] Analyzer for errors in code ? — David Unric <dunric29a@...>

Hello,

19 messages 2010/11/09

[#373421] help with code, new to programming — Steve Rees <stevoreesimo@...>

I am new to programming and have been learning Ruby using online

13 messages 2010/11/09

[#373479] ruby ORM — zuerrong <zuerrong@...>

Hello,

64 messages 2010/11/11
[#373480] Re: ruby ORM — Sam Duncan <sduncan@...> 2010/11/11

I've been writing Ruby for three days now. DataMapper seems very good.

[#373607] ORM's - Don't Do It! — Mike Stephens <rubfor@...> 2010/11/12

Sam Duncan wrote in post #960638:

[#373616] Re: ORM's - Don't Do It! — Phillip Gawlowski <cmdjackryan@...> 2010/11/12

On Fri, Nov 12, 2010 at 5:47 PM, Mike Stephens <rubfor@recitel.net> wrote:

[#373634] Re: ORM's - Don't Do It! — Petite Abeille <petite.abeille@...> 2010/11/12

[#373663] Re: ORM's - Don't Do It! — Phillip Gawlowski <cmdjackryan@...> 2010/11/13

On Fri, Nov 12, 2010 at 9:56 PM, Petite Abeille

[#373666] Re: ORM's - Don't Do It! — Mike Stephens <rubfor@...> 2010/11/13

My problem is the mismatch.

[#373676] Re: ORM's - Don't Do It! — Phillip Gawlowski <cmdjackryan@...> 2010/11/13

On Sat, Nov 13, 2010 at 10:54 AM, Mike Stephens <rubfor@recitel.net> wrote:

[#373746] Re: ORM's - Don't Do It! — "Skye Shaw!@#$" <skye.shaw@...> 2010/11/14

On Nov 12, 8:47=A0am, Mike Stephens <rub...@recitel.net> wrote

[#374853] DRM Principle - Don't Repeat Microsoft — Mike Stephens <rubfor@...> 2010/12/03

I was thinking about this last night and it's part of a belief I have

[#373481] what's an object? — "Eva" <eva54321@...>

SSdtIGFsc28gc3dpdGNoaW5nIGZyb20gcGVybCBhbmQgcGhwLgpJJ20gbm90IHN1cmUgaW4gcnVi

55 messages 2010/11/11
[#373482] Re: what's an object? — Alex Stahl <astahl@...5.com> 2010/11/11

Simple answer: everything. Everything is considered an object,

[#373490] Re: what's an object? — "Y. NOBUOKA" <nobuoka@...> 2010/11/11

> Simple answer: everything. Everything is considered an object,

[#373500] Re: what's an object? — Alex Stahl <astahl@...5.com> 2010/11/11

Not that I know the internals of the language well enough to debate the

[#373504] Re: what's an object? — "Y. NOBUOKA" <nobuoka@...> 2010/11/11

> Not that I know the internals of the language well enough to debate the

[#373511] Re: what's an object? — Alex Stahl <astahl@...5.com> 2010/11/11

Fair enough. The link even cites the Ruby spec to indicate that

[#373522] Re: what's an object? — "Y. NOBUOKA" <nobuoka@...> 2010/11/11

Did you recognize the difference between a method and a Method object?

[#373528] Re: what's an object? — Josh Cheek <josh.cheek@...> 2010/11/11

Disclaimer: I seem to be in a crabby mood this morning. I went back over it

[#373569] Re: what's an object? — "Y. NOBUOKA" <nobuoka@...> 2010/11/12

Hi, Josh

[#373571] Re: what's an object? — Josh Cheek <josh.cheek@...> 2010/11/12

On Fri, Nov 12, 2010 at 3:01 AM, Xavier Noria <fxn@hashref.com> wrote:

[#373572] Re: what's an object? — Xavier Noria <fxn@...> 2010/11/12

On Fri, Nov 12, 2010 at 12:25 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

[#373576] Re: what's an object? — Robert Dober <robert.dober@...> 2010/11/12

On Fri, Nov 12, 2010 at 12:38 PM, Xavier Noria <fxn@hashref.com> wrote:

[#373582] Re: what's an object? — Xavier Noria <fxn@...> 2010/11/12

On Fri, Nov 12, 2010 at 1:09 PM, Robert Dober <robert.dober@gmail.com> wrot=

[#373536] Parsing XML with Ruby — jackster the jackle <johnsheahan@...>

I need to hit an https link and pass a username and password in order to

17 messages 2010/11/12
[#373547] Re: Parsing XML with Ruby — jackster the jackle <johnsheahan@...> 2010/11/12

It seems to be working...here is my test code:

[#373539] Scheme's (cond ((assertion) (value))...(else (value))) statement implemented in ruby? — timr <timrandg@...>

Hi Rubyists,

10 messages 2010/11/12

[#373599] help sorting objects by their instance field — Aaron Haas <aaron4osu@...>

I'm trying to figure out how to sort objects in an array by one of their

14 messages 2010/11/12

[#373618] Fast Debugger (Ruby 1.9.2, DevKit 4.5.0, JDK 6u22, NetBeans 6.9.1) — Allan Chin <achin5957@...>

I've been trying to run this configuration in debug mode on my Windows

17 messages 2010/11/12

[#373680] an each/block problem — Paul Roche <prpaulroche@...>

Hi, I want to take the value from an each method and place it in a

12 messages 2010/11/13

[#373722] Mysql::Result .each_hash - unexpected result — Andy Tolle <durexlw.register@...>

Consider the following code:

12 messages 2010/11/14
[#373738] Re: Mysql::Result .each_hash - unexpected result — botp <botpena@...> 2010/11/14

On Sun, Nov 14, 2010 at 5:55 PM, Andy Tolle <durexlw.register@gmail.com> wr=

[#373745] Re: Mysql::Result .each_hash - unexpected result — Andy Tolle <durexlw.register@...> 2010/11/14

botp wrote in post #961345:

[#373773] please help load from txt — Lark Work <lars_werkman@...>

hi i new to this forum and i have a problem a made a script containing a

17 messages 2010/11/15

[#373787] Can't get Ruby programs to work from Command Prompt — Dd Dd <dd25@...>

Hello; I'm having a problem running Ruby programs through the command

10 messages 2010/11/15

[#373852] cool.io 0.9.0: a cool event framework for Ruby (formerly known as Rev) based on libev — Tony Arcieri <tony.arcieri@...>

Github: https://github.com/tarcieri/cool.io

15 messages 2010/11/16
[#374061] Re: [ANN] cool.io 0.9.0: a cool event framework for Ruby (formerly known as Rev) based on libev — Eric Wong <normalperson@...> 2010/11/19

Tony Arcieri <tony.arcieri@medioh.com> wrote:

[#373930] Ruby Not observing DRY principle — flebber <flebber.crue@...>

HI I am hoping you can give me some guidance. I feel I really am

17 messages 2010/11/18

[#373990] Where to start from? — Ruby Me <i_baseet@...>

Hi guys,

16 messages 2010/11/18

[#374001] Ruby Programming — Tridib Bandopadhyay <tridib04@...>

Hello

18 messages 2010/11/18

[#374104] gsub and backslashes — Ralph Shnelvar <ralphs@...32.com>

Consider the string

16 messages 2010/11/20
[#374151] Re: gsub and backslashes — Brian Candler <b.candler@...> 2010/11/21

Ralph Shnelvar wrote in post #962847:

[#374114] Problem regarding regular expression — Stanford Ng <ngkooinam@...>

puts( /^[a-z 0-9]*$/ =~ 'Well hello 123' ) # no match due to ^ and

12 messages 2010/11/21

[#374127] why i can't find my ruby ? — Pen Ttt <myocean135@...>

i installed ruby this way:

18 messages 2010/11/21

[#374210] system() or process.create? — Fengfeng Li <lifengfeng@...>

Hi everyone,

13 messages 2010/11/23

[#374229] Regex negative look-behind bug? — Ruby Nuby <b1st@...>

irb, Ruby 1.9.1

14 messages 2010/11/23

[#374232] Ruby 1.8 vs 1.9 — Peter Pincus <peter.pincus@...>

Hi,

85 messages 2010/11/23
[#374313] Re: Ruby 1.8 vs 1.9 — Jörg W Mittag <JoergWMittag+Ruby@...> 2010/11/25

David Masover wrote:

[#374394] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/26

On Wednesday, November 24, 2010 08:40:22 pm J=F6rg W Mittag wrote:

[#374406] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/26

On Fri, Nov 26, 2010 at 1:42 AM, David Masover <ninja@slaphack.com> wrote:

[#374425] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/27

On Friday, November 26, 2010 05:51:38 am Phillip Gawlowski wrote:

[#374444] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/27

On Sat, Nov 27, 2010 at 9:04 AM, David Masover <ninja@slaphack.com> wrote:

[#374448] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/27

On Saturday, November 27, 2010 11:41:59 am Phillip Gawlowski wrote:

[#374452] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/27

On Sat, Nov 27, 2010 at 7:50 PM, David Masover <ninja@slaphack.com> wrote:

[#374462] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/28

On Saturday, November 27, 2010 02:47:12 pm Phillip Gawlowski wrote:

[#374470] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/28

On Sun, Nov 28, 2010 at 1:56 AM, David Masover <ninja@slaphack.com> wrote:

[#374472] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/28

On Sunday, November 28, 2010 08:00:18 am Phillip Gawlowski wrote:

[#374475] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/28

On Sun, Nov 28, 2010 at 5:33 PM, David Masover <ninja@slaphack.com> wrote:

[#374488] Re: Ruby 1.8 vs 1.9 — David Masover <ninja@...> 2010/11/28

On Sunday, November 28, 2010 11:19:06 am Phillip Gawlowski wrote:

[#374241] Re: Ruby 1.8 vs 1.9 — Chuck Remes <cremes.devlist@...> 2010/11/23

[#374260] Re: Ruby 1.8 vs 1.9 — Brian Candler <b.candler@...> 2010/11/24

Chuck Remes wrote in post #963430:

[#374264] Re: Ruby 1.8 vs 1.9 — Michael Fellinger <m.fellinger@...> 2010/11/24

On Wed, Nov 24, 2010 at 8:14 PM, Brian Candler <b.candler@pobox.com> wrote:

[#374274] Re: Ruby 1.8 vs 1.9 — Brian Candler <b.candler@...> 2010/11/24

Michael Fellinger wrote in post #963539:

[#374278] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/24

On Wed, Nov 24, 2010 at 4:15 PM, Brian Candler <b.candler@pobox.com> wrote:

[#374281] Re: Ruby 1.8 vs 1.9 — Brian Candler <b.candler@...> 2010/11/24

Phillip Gawlowski wrote in post #963602:

[#374287] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/24

On Wed, Nov 24, 2010 at 5:09 PM, Brian Candler <b.candler@pobox.com> wrote:

[#374293] Re: Ruby 1.8 vs 1.9 — Josh Cheek <josh.cheek@...> 2010/11/24

On Wed, Nov 24, 2010 at 12:20 PM, Phillip Gawlowski <

[#374294] Re: Ruby 1.8 vs 1.9 — Phillip Gawlowski <cmdjackryan@...> 2010/11/24

On Wed, Nov 24, 2010 at 8:02 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

[#374332] Re: Ruby 1.8 vs 1.9 — Robert Klemme <shortcutter@...> 2010/11/25

On Wed, Nov 24, 2010 at 5:09 PM, Brian Candler <b.candler@pobox.com> wrote:

[#374299] Ruby's "More than one way to do things." — Jason Lillywhite <jason.lillywhite@...>

There is one point made about Python vs. Ruby on this site:

23 messages 2010/11/24

[#374431] relative-require v1.0 — "zimbatm ..." <jonas@...>

relative-require.rb

12 messages 2010/11/27

[#374437] How to use Ruby like shell script? — Yu-Hsuan Lai <raincolee@...>

Can I use ruby like my linux shell script(e.x. bash)?(or on the other hand,

21 messages 2010/11/27
[#374446] Re: How to use Ruby like shell script? — James Edward Gray II <james@...> 2010/11/27

On Nov 27, 2010, at 8:51 AM, Yu-Hsuan Lai wrote:

[#374550] ruby on server side — Rajesh Huria <rajesh.huria@...>

Hi,

13 messages 2010/11/29

[#374557] Help sorting an array — Jim Burgess <jack.zelig@...>

Hi,

32 messages 2010/11/29
[#374730] Re: Help sorting an array — Mike Stephens <rubfor@...> 2010/12/01

If you've ever read "Real Programmers don't use Pascal" (see

[#374747] Re: Help sorting an array — Ammar Ali <ammarabuali@...> 2010/12/01

On Wed, Dec 1, 2010 at 8:30 PM, Mike Stephens <rubfor@recitel.net> wrote:

[#374751] Try it and see. — Mike Stephens <rubfor@...> 2010/12/01

Ammar Ali wrote in post #965529:

[#374756] Re: Try it and see. — David Masover <ninja@...> 2010/12/01

On Wednesday, December 01, 2010 03:04:42 pm Mike Stephens wrote:

[#374771] Re: Try it and see. — Mike Stephens <rubfor@...> 2010/12/02

David Masover wrote in post #965565:.

[#374587] RFC Future Ruby hash literal syntax — Michael Kaelbling <michael.kaelbling@...>

REQUEST FOR COMMENTS: Change to future Ruby hash literal syntax

15 messages 2010/11/29

[#374619] installing ncurses and IDE — Nikita Kuznetsov <moog_master@...>

Hi all, I was recently advised to use ncurses in order to do some event

11 messages 2010/11/30

[#374632] 'require' is not recognised — Tara Keane <tararakeane@...>

New to Ruby and trying to run benchmark

14 messages 2010/11/30

ANN main-4.4.0

From: "ara.t.howard" <ara.t.howard@...>
Date: 2010-11-25 17:10:15 UTC
List: ruby-talk #374367
NAME
  main.rb

SYNOPSIS
  a class factory and dsl for generating command line programs real
quick

URI
  http://codeforpeople.com/lib/ruby/
  http://rubyforge.org/projects/codeforpeople/
  http://github.com/ahoward/main

INSTALL
  gem install main

DESCRIPTION
  main.rb features the following:

    - unification of option, argument, keyword, and environment
parameter
      parsing
    - auto generation of usage and help messages
    - support for mode/sub-commands
    - io redirection support
    - logging hooks using ruby's built-in logging mechanism
    - intelligent error handling and exit codes
    - use as dsl or library for building Main objects
    - parsing user defined ARGV and ENV
    - zero requirements for understanding the obtuse apis of *any*
command
      line option parsers
    - leather pants

  in short main.rb aims to drastically lower the barrier to writing
uniform
  command line applications.

  for instance, this program

    require 'main'

    Main {
      argument 'foo'
      option 'bar'

      def run
        p params['foo']
        p params['bar']
        exit_success!
      end
    }

  sets up a program which requires one argument, 'bar', and which may
accept one
  command line switch, '--foo' in addition to the single option/mode
which is always
  accepted and handled appropriately: 'help', '--help', '-h'.  for the
most
  part main.rb stays out of your command line namespace but insists
that your
  application has at least a help mode/option.

  main.rb supports sub-commands in a very simple way

    require 'main'

    Main {
      mode 'install' do
        def run() puts 'installing...' end
      end

      mode 'uninstall' do
        def run() puts 'uninstalling...' end
      end
    }

  which allows a program, called 'a.rb', to be invoked as

    ruby a.rb install

  and

    ruby a.rb uninstall

  for simple programs main.rb is a real time saver but it's for more
complex
  applications where main.rb's unification of parameter parsing, class
  configuration dsl, and auto-generation of usage messages can really
streamline
  command line application development.  for example the following
'a.rb'
  program:

    require 'main'

    Main {
      argument('foo'){
        cast :int
      }
      keyword('bar'){
        arity 2
        cast :float
        defaults 0.0, 1.0
      }
      option('foobar'){
        argument :optional
        description 'the foobar option is very handy'
      }
      environment('BARFOO'){
        cast :list_of_bool
        synopsis 'export barfoo=value'
      }

      def run
        p params['foo'].value
        p params['bar'].values
        p params['foobar'].value
        p params['BARFOO'].value
      end
    }

  when run with a command line of

    BARFOO=true,false,false ruby a.rb 42 bar=40 bar=2 --foobar=a

  will produce

    42
    [40.0, 2.0]
    "a"
    [true, false, false]

  while a command line of

    ruby a.rb --help

  will produce

    NAME
      a.rb

    SYNOPSIS
      a.rb foo [bar=bar] [options]+

    PARAMETERS
      * foo [ 1 -> int(foo) ]

      * bar=bar [ 2 ~> float(bar=0.0,1.0) ]

      * --foobar=[foobar] [ 1 ~> foobar ]
          the foobar option is very handy

      * --help, -h

      * export barfoo=value

  and this shows how all of argument, keyword, option, and environment
parsing
  can be declartively dealt with in a unified fashion - the dsl for
all
  parameter types is the same - and how auto synopsis and usage
generation saves
  keystrokes.  the parameter synopsis is compact and can be read as

      * foo [ 1 -> int(foo) ]

        'one argument will get processed via int(argument_name)'

          1        : one argument
          ->       : will get processed (the argument is required)
          int(foo) : the cast is int, the arg name is foo

      * bar=bar [ 2 ~> float(bar=0.0,1.0) ]

        'two keyword arguments might be processed via
float(bar=0.0,1.0)'

          2                  : two arguments
          ~>                 : might be processed (the argument is
optional)
          float(bar=0.0,1.0) : the cast will be float, the default
values are
                               0.0 and 1.0

      * --foobar=[foobar] [ 1 ~> foobar ]

        'one option with optional argument may be given directly'

      * --help, -h

        no synopsis, simple switch takes no args and is not required

      * export barfoo=value

        a user defined synopsis

SAMPLES

  <========< samples/a.rb >========>

  ~ > cat samples/a.rb

    require 'main'

    ARGV.replace %w( 42 ) if ARGV.empty?

    Main {
      argument('foo'){
        required                    # this is the default
        cast :int                   # value cast to Fixnum
        validate{|foo| foo == 42}   # raises error in failure case
        description 'the foo param' # shown in --help
      }

      def run
        p params['foo'].given?
        p params['foo'].value
      end
    }

  ~ > ruby samples/a.rb

    true
    42


  <========< samples/b.rb >========>

  ~ > cat samples/b.rb

    require 'main'

    ARGV.replace %w( 40 1 1 ) if ARGV.empty?

    Main {
      argument('foo'){
        arity 3                             # foo will given three
times
        cast :int                           # value cast to Fixnum
        validate{|foo| [40,1].include? foo} # raises error in failure
case
        description 'the foo param'         # shown in --help
      }

      def run
        p params['foo'].given?
        p params['foo'].values
      end
    }

  ~ > ruby samples/b.rb

    true
    [40, 1, 1]


  <========< samples/c.rb >========>

  ~ > cat samples/c.rb

    require 'main'

    ARGV.replace %w( foo=40 foo=2 bar=false ) if ARGV.empty?

    Main {
      keyword('foo'){
        required  # by default keywords are not required
        arity 2
        cast :float
      }
      keyword('bar'){
        cast :bool
      }

      def run
        p params['foo'].given?
        p params['foo'].values
        p params['bar'].given?
        p params['bar'].value
      end
    }

  ~ > ruby samples/c.rb

    true
    [40.0, 2.0]
    true
    false


  <========< samples/d.rb >========>

  ~ > cat samples/d.rb

    require 'main'

    ARGV.replace %w( --foo=40 -f2 ) if ARGV.empty?

    Main {
      option('foo', 'f'){
        required  # by default options are not required, we could use
'foo=foo'
                  # above as a shortcut
        argument_required
        arity 2
        cast :float
      }

      option('bar=[bar]', 'b'){  # note shortcut syntax for optional
args
        # argument_optional      # we could also use this method
        cast :bool
        default false
      }

      def run
        p params['foo'].given?
        p params['foo'].values
        p params['bar'].given?
        p params['bar'].value
      end
    }

  ~ > ruby samples/d.rb

    true
    [40.0, 2.0]
    nil
    false


  <========< samples/e.rb >========>

  ~ > cat samples/e.rb

    require 'main'

    ARGV.replace %w( x y argument )

    Main {
      argument 'argument'
      option 'option'

      def run() puts 'run' end

      mode 'a' do
        option 'a-option'
        def run() puts 'a-run' end
      end

      mode 'x' do
        option 'x-option'

        def run() puts 'x-run' end

          mode 'y' do
            option 'y-option'

            def run() puts 'y-run' end
          end
      end
    }

  ~ > ruby samples/e.rb

    y-run


  <========< samples/f.rb >========>

  ~ > cat samples/f.rb

    require 'main'

    ARGV.replace %W( compress /data )

    Main {
      argument('directory'){ description 'the directory to operate
on' }

      option('force'){ description 'use a bigger hammer' }

      def run
        puts 'this is how we run when no mode is specified'
      end

      mode 'compress' do
        option('bzip'){ description 'use bzip compression' }

        def run
          puts 'this is how we run in compress mode'
        end
      end

      mode 'uncompress' do
        option('delete-after'){ description 'delete orginal file after
uncompressing' }

        def run
          puts 'this is how we run in un-compress mode'
        end
      end
    }

  ~ > ruby samples/f.rb

    this is how we run in compress mode


  <========< samples/g.rb >========>

  ~ > cat samples/g.rb

    require 'main'

    ARGV.replace %w( 42 ) if ARGV.empty?

    Main {
      argument( 'foo' )
      option( 'bar' )

      run { puts "This is what to_options produces:
#{params.to_options.inspect}" }
    }

  ~ > ruby samples/g.rb

    This is what to_options produces: {"help"=>nil, "foo"=>"42",
"bar"=>nil}


  <========< samples/h.rb >========>

  ~ > cat samples/h.rb

    require 'main'

    # block-defaults are instance_eval'd in the main instance and be
combined with
    # mixins
    #
    # ./h.rb   #=> forty-two
    # ./h.rb a #=> 42
    # ./h.rb b #=> 42.0
    #

    Main {
      fattr :default_for_foobar => 'forty-two'

      option(:foobar) do
        default{ default_for_foobar }
      end

      mixin :foo do
        fattr :default_for_foobar => 42
      end

      mixin :bar do
        fattr :default_for_foobar => 42.0
      end


      run{ p params[:foobar].value }

      mode :a do
        mixin :foo
      end

      mode :b do
        mixin :bar
      end
    }

  ~ > ruby samples/h.rb

    "forty-two"


  <========< samples/j.rb >========>

  ~ > cat samples/j.rb

    #!/usr/bin/env ruby

    require 'open-uri'

    require 'main'
    require 'digest/sha2'

    # you have access to a sequel/amalgalite/sqlite db for free
    #

    Main {
      name :i_can_haz_db

      db {
        create_table(:mp3s) do
          primary_key :id
          String :url
          String :sha
        end unless table_exists?(:mp3s)
      }

      def run
        url = 'http://s3.amazonaws.com/drawohara.com.mp3/ween-
voodoo_lady.mp3'
        mp3 = open(url){|fd| fd.read}
        sha = Digest::SHA2.hexdigest(mp3)

        db[:mp3s].insert(:url => url, :sha => sha)
        p db[:mp3s].all
        p db
      end
    }

  ~ > ruby samples/j.rb

    [{:url=>"http://s3.amazonaws.com/drawohara.com.mp3/ween-
voodoo_lady.mp3", :sha=>"54c99ac7588dcfce1e70540b734805e9c69ff98dcca001e6f2bdec140fb0f9dc", :id=>1},
{:url=>"http://s3.amazonaws.com/drawohara.com.mp3/ween-
voodoo_lady.mp3", :sha=>"54c99ac7588dcfce1e70540b734805e9c69ff98dcca001e6f2bdec140fb0f9dc", :id=>2}]
    #<Sequel::Amalgalite::Database: "amalgalite://Users/
ahoward/.i_can_haz_db/db.sqlite">



DOCS
  test/main.rb
  vim -p lib/main.rb lib/main/*rb
  API section below

HISTORY
  4.4.0
    - support for automatic sequel/sqlite/amalgalite dbs for
persistent state
      across invocations

        Main {
          db {
            create_table :foo do
              String key
              String val
            end unless table_exists? :foo
          }

          def run
            db[:foo].create(:key => 'using', :val => 'amalgalite')
          end
        }

      - support for automatic config files with auto populated
template data

          Main {
            config :email => 'your.addy@gmail.com', :password => 'pa$
$word'

            def run
              email = config[:email]
            end
          }

      - new paramter types :pathname, :path, :slug, :input,
and :output

      - input/output parameters.  can be filenames or '-' to supply
        stdin/stdout respectively

          Main {
            input :i
            output :o

            def run
              i = params[:i].value
              o = params[:o].value

              line = i.gets
              o.puts line
            end
          }

       - clean up warnings running with 'ruby -w'

       - fix a failing test

       - ability to ignore parameters in sub modes

          Main {
            argument :foo
            argument :bar

            def run
              p param[:bar].value
            end

            mode :ignoring do
              params[:foo].ignore!
            end
          }
  4.0.0
    - avoid duping ios.  new methods Main.push_ios! and Main.pop_ios!
are
    utilized for testing.  this was done to make it simple to wrap
    daemon/servolux programs around main, althought not strictly
required.
    not the version bump - there is not reason to expect existing main
    programs to break, but it *is* and interface change which requires
a major
    version bump.

  3.0.0
    - major refactor to support modes via module/extend vs.
subclassing.
    MIGHT NOT be backward compatible, though no known issues thus far.

  2.9.0
    - support ruby 1.9

  2.8.3
    - support for block defaults


  2.8.2
    - fixes and tests for negative arity/attr arguments, options, eg

        argument(:foo){
          arity -1
        }

        def run  # ARGV == %w( a b c )
          p foo  #=> %w( a b c )
        end

      thanks nathan

  2.8.1
    - move from attributes.rb to fattr.rb

  2.8.0
    - added 'to_options' method for Parameter::Table.  this allows you
to convert
      all the parameters to a simple hash.
      for example

        Main {
          option 'foo'
          argument 'baz'

          run { puts params.to_options.inspect }

        }

  2.7.0
    - removed bundled arrayfields and attributes.  these are now
dependancies
      mananged by rubygems.  a.k.a. you must have rubygems installed
for main
      to work.

  2.6.0
    - added 'mixin' feaature for storing, and later evaluating a block
of
      code.  the purpose of this is for use with modes where you want
to keep
      your code dry, but may not want to define something in the base
class
      for all to inherit.  'mixin' allows you to define the code to
inherit
      once and the selectively drop it in child classes (modes) on
demand.
      for example

        Main {
          mixin :foobar do
            option 'foo'
            option 'bar'
          end

          mode :install do
            mixin :foobar
          end

          mode :uninstall do
            mixin :foobar
          end

          mode :clean do
          end
        }

    - mode definitions are now deferred to the end of the Main block,
so you
      can do this

        Main {
          mode 'a' do
            mixin :foo
          end

          mode 'b' do
            mixin :foo
          end

          def inherited_method
            42
          end

          mixin 'foo' do
            def another_inherited_method
              'forty-two'
            end
          end
        }

    - added sanity check at end of paramter contruction

    - improved auto usage generation when arity is used with arguments

    - removed 'p' shortcut in paramerter dsl because it collided with
      Kernel.p.  it's now called 'param'.  this method is availble
*inside* a
      parameter definition

        option('foo', 'f'){
          synopsis "arity = #{ param.arity }"
        }

    - fixed bug where '--' did not signal the end of parameter parsing
in a
      getoptlong compliant way

    - added (before/after)_parse_parameters, (before/
after)_initialize, and
      (before/after)_run hooks

    - fixed bug where adding to usage via

        usage['my_section'] = 'custom message'

      totally horked the default auto generated usage message

    - updated dependancies in gemspec.rb for attributes (~> 5.0.0) and
      arrayfields (~> 4.3.0)

    - check that client code defined run, iff not wrap_run! is
called.  this is
      so mains with a mode, but no run defined, still function
correctly when
      passed a mode

    - added new shortcut for creating accessors for parameters.  for
example

        option('foo'){
          argument :required
          cast :int
          attr
        }

        def run
          p foo ### this attr will return the parameter's *value*
        end

      a block can be passed to specify how to extract the value from
the
      parameter

        argument('foo'){
          optional
          default 21
          cast :int
          attr{|param| param.value * 2}
        }

        def run
          p foo #=> 42
        end

    - fixed bug where 'abort("message")' would print "message" twice
on exit
      if running under a nested mode (yes again - the fix in 2.4.0
wasn't
      complete)

    - added a time cast, which uses Time.parse

        argument('login_time'){ cast :time }

    - added a date cast, which uses Date.parse

        argument('login_date'){ cast :date }


  2.5.0
    - added 'examples', 'samples', and 'api' kewords to main dsl.
each
      keyword takes a list of strings which will be included in the
help
      message

        Main {
          examples "foobar example", "barfoo example"

          samples <<-txt
            do this

            don't do that
          txt

          api %(
            foobar string, hash

            barfoo hash, string
          )
        }

      results in a usage message with sections like

      ...

      EXAMPLES
        foobar example
        barfoo example

      SAMPLES
        do this

        don't do that

      API
        foobar string, hash

        barfoo hash, string

      ...

  2.4.0
    - fixed bug where 'abort("message")' would print "message" twice
on exit
      if running under a nested mode.

    - allowed parameters to be overridden completely in subclasses
(modes)

  2.3.0
    - re-worked Main.new such that client code may define an
#initialize
      methods and the class will continue to work.  that is to say
it's fine
      to do this

        Main {
          def initialize
            @a = 42
          end

          def run
            p @a
          end

          mode 'foo' do
            def run
              p @a
            end
          end
        }

      the client #initialize will be called *after* main has done it's
normal
      initialization so things like @argv, @env, and @stdin will all
be there
      in initialize.  of course you could have done this before but
you'd have
      to both call super and call it with the correct arguments - now
you can
      simply ignore it.

  2.2.0
    - added ability for parameter dsl error handlers to accept an
argument,
      this will be passed the current error.  for example

        argument(:x) do
          arity 42

          error do |e|
            case e
              when Parameter::Arity
            ...
          end
        end

    - refined the mode parsing a bit: modes can now be abbreviated to
uniqness
      and, when the mode is ambiuous, a nice error message is printed,
for
      example:

        ambiguous mode: in = (inflate or install)?

  2.1.0
    - added custom error handling dsl for parameters, this includes
the ability
      to prepend, append, or replace the standard error handlers:

        require 'main'

        Main {
          argument 'x' do
            error :before do
              puts 'this fires *before* normal error handling using
#instance_eval...'
            end

            error do
              puts 'this fires *instead of* normal error handling
using #instance_eval...'
            end

            error :after do
              puts 'this fires *after* normal error handling using
#instance_eval...'
            end
          end

          run(){ p param['x'].given? }
        }

    - added ability to exit at any time bypassing *all* error handling
using
      'throw :exit, 42' where 42 is the desired exit status.  throw
without a
      status simply exits with 0.

    - added 'help!' method which simply dumps out usage and exits

  2.0.0
    - removed need for proxy.rb via Main::Base.wrap_run!
    - added error handling hooks for parameter parsing
    - bundled arrayfields, attributes, and pervasives although gems
are tried
      first
    - softened error messages for parameter parsing errors: certain
classes of
      errors are now 'softspoken' and print only the message, not the
entire
      stacktrace, to stderr.  much nicer for users.  this is
configurable.
    - added subcommand/mode support
    - added support for user defined exception handling on top level
      exceptions/exits
    - added support for negative arity.  this users ruby's own arity
      semantics, for example:

        lambda{|*a|}.arity     == -1
        lambda{|a,*b|}.arity   == -2
        lambda{|a,b,*c|}.arity == -3
        ...

      in otherwords parameters now support 'zero or more', 'one or
more' ...
      'n or more' argument semantics

  1.0.0
    - some improved usage messages from jeremy hinegardner

  0.0.2
    - removed dependancy on attributes/arrayfields.  main now has zero
gem
      dependancies.

    - added support for io redirection.  redirection of stdin, stdout,
and
      stderr can be done to any io like object or object that can be
      inerpreted as a pathname (object.to_s)

    - main objects can now easily be created and run on demand, which
makes
      testing a breeze

        def test_unit_goodness!
          main =
            Main.new{
              stdout StringIO.new
              stderr '/dev/null'

              def run
                puts 42
              end
            }

          main.run
          main.stdout.rewind

          assert main.stdout.read == "42\n"
        end

    - added API section to readme and called it 'docs'

    - wrote a bunch more tests.  there are now 42 of them.

  0.0.1

    initial version.  this version extracts much of the functionality
of alib's
    (gen install alib) Alib.script main program generator and also
some of jim's
    freeze's excellent CommandLine::Aplication into what i hope is a
simpler and
    more unified interface

API

  Main {

 
###########################################################################
  #                       CLASS LEVEL
API                                   #
 
###########################################################################
  #
  # the name of the program, auto-set and used in usage
  #
    program 'foo.rb'
  #
  # a short description of program functionality, auto-set and used in
usage
  #
    synopsis "foo.rb arg [options]+"
  #
  # long description of program functionality, used in usage iff set
  #
    description <<-hdoc
      this text will automatically be indented to the right level.

      it should describe how the program works in detail
    hdoc
  #
  # used in usage iff set
  #
    author 'ara.t.howard@gmail.com'
  #
  # used in usage
  #
    version '0.0.42'
  #
  # stdin/out/err can be anthing which responds to read/write or a
string
  # which will be opened as in the appropriate mode
  #
    stdin '/dev/null'
    stdout '/dev/null'
    stderr open('/dev/null', 'w')
  #
  # the logger should be a Logger object, something 'write'-able, or a
string
  # which will be used to open the logger.  the logger_level specifies
the
  # initalize verbosity setting, the default is Logger::INFO
  #
    logger(( program + '.log' ))
    logger_level Logger::DEBUG
  #
  # you can configure exit codes.  the defaults are shown
  #
    exit_success # 0
    exit_failure # 1
    exit_warn    # 42
  #
  # the usage object is rather complex.  by default it's an object
which can
  # be built up in sections using the
  #
  #   usage["BUGS"] = "something about bugs'
  #
  # syntax to append sections onto the already pre-built usage message
which
  # contains program, synopsis, parameter descriptions and the like
  #
  # however, you always replace the usage object wholesale with one of
your
  # chosing like so
  #
    usage <<-txt
      my own usage message
    txt

 
###########################################################################
  #                         MODE
API                                        #
 
###########################################################################
  #
  # modes are class factories that inherit from their parent class.
they can
  # be nested *arbitrarily* deep.  usage messages are tailored for
each mode.
  # modes are, for the most part, independant classes but parameters
are
  # always a superset of the parent class - a mode accepts all of it's
parents
  # paramters *plus* and additional ones
  #
    option 'inherited-option'
    argument 'inherited-argument'

    mode 'install' do
      option 'force' do
        description 'clobber existing installation'
      end

      def run
        inherited_method()
        puts 'installing...'
      end

      mode 'docs' do
        description 'installs the docs'

        def run
          puts 'installing docs...'
        end
      end
    end

    mode 'un-install' do
      option 'force' do
        description 'remove even if dependancies exist'
      end

      def run
        inherited_method()
        puts 'un-installing...'
      end
    end

    def run
      puts 'no mode yo?'
    end

    def inherited_method
      puts 'superclass_method...'
    end


 
###########################################################################
  #                         PARAMETER
API                                   #
 
###########################################################################
  #
  # all the parameter types of argument|keyword|option|environment
share this
  # api.  you must specify the type when the parameter method is used.
  # alternatively used one of the shortcut methods
  # argument|keyword|option|environment.  in otherwords
  #
  #   parameter('foo'){ type :option }
  #
  # is synonymous with
  #
  #   option('foo'){ }
  #
    option 'foo' {
    #
    # required - whether this paramter must by supplied on the command
line.
    # note that you can create 'required' options with this keyword
    #
      required # or required true
    #
    # argument_required - applies only to options.
    #
      argument_required # argument :required
    #
    # argument_optional - applies only to options.
    #
      argument_optional # argument :optional
    #
    # cast - should be either a lambda taking one argument, or a
symbol
    # designation one of the built in casts defined in Main::Cast.
supported
    # types are :boolean|:integer|:float|:numeric|:string|:uri.  built-
in
    # casts can be abbreviated
    #
      cast :int
    #
    # validate - should be a lambda taking one argument and returning
    # true|false
    #
      validate{|int| int == 42}
    #
    # synopsis - should be a concise characterization of the
paramter.  a
    # default synopsis is built automatically from the parameter.
this
    # information is displayed in the usage message
    #
      synopsis '--foo'
    #
    # description - a longer description of the paramter.  it appears
in the
    # usage also.
    #
      description 'a long description of foo'
    #
    # arity - indicates how many times the parameter should appear on
the
    # command line.  the default is one.  negative arities are
supported and
    # follow the same rules as ruby methods/procs.
    #
      arity 2
    #
    # default - you can provide a default value in case none is
given.  the
    # alias 'defaults' reads a bit nicer when you are giving a list of
    # defaults for paramters of > 1 arity
    #
      defaults 40, 2
    #
    # you can add custom per-parameter error handlers using the
following
    #
      error :before do
        puts 'this fires *before* normal error handling using
#instance_eval...'
      end

      error do
        puts 'this fires *instead of* normal error handling using
#instance_eval...'
      end

      error :after do
        puts 'this fires *after* normal error handling using
#instance_eval...'
      end
    }

 
###########################################################################
  #                       INSTANCE LEVEL
API                                #
 
###########################################################################
  #
  # you must define a run method.  it is the only method you must
define.
  #
    def run
      #
      # all parameters are available in the 'params' hash and via the
alias
      # 'param'.  it can be indexed via string or symbol.  the values
are all
      # Main::Parameter objects
      #
        foo = params['foo']
      #
      # the given? method indicates whether or not the parameter was
given on
      # the commandline/environment, etc.  in particular this will not
be true
      # when a default value was specified but no parameter was given
      #
        foo.given?
      #
      # the list of all values can be retrieved via 'values'.  note
that this
      # is always an array.
      #
        p foo.values
      #
      # the __first__ value can be retrieved via 'value'.  note that
this
      # never an array.
      #
        p foo.value
      #
      # the methods debug|info|warn|error|fatal are delegated to the
logger
      # object
      #
        info{ "this goes to the log" }
      #
      # you can set the exit_status at anytime.  this status is used
when
      # exiting the program.  exceptions cause this to be ext_failure
if, and
      # only if, the current value was exit_success.  in otherwords an
      # un-caught exception always results in a failing exit_status
      #
        exit_status exit_failure
      #
      # a few shortcuts both set the exit_status and exit the program.
      #
        exit_success!
        exit_failure!
        exit_warn!
    end

  }

In This Thread

Prev Next