How to DRY code to prompt for parameters

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710.

Running this code under SciTE produces, for example:
Getting parms
  Account Number: 123
  Report Period: 456
Showing parms
  @acct_num = 123
  @acct_period = 456

It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names. That led me to
using case statements to accept input values and then populate the
instance variables.

Can anyone suggest how I can use the instance variables as targets in
lieu of the case statements? BTW, I want to get this working with
meta-programming. I don't want to use some other approach, such as a
plug-in for getting arguments.

Thanks in Advance,
Richard

It is excessively verbose because you wrote 53 lines when 4 would do:

print "Account Number: "
@acct_num = gets.to_i
print "Report Period: "
@acct_period = gets.to_i

There is nothing wrong with that code. It doesn't have to be 13x more complex to ask the user 2 simple questions.

The definition of DRY is "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system" not "ZOMG I see a 2 line pattern! must kill!"

Please. Do the simplest thing that could possibly work.

P.S. AGAIN with the tabs. I almost didn't write this email at all just because reading your code is too hard.

···

On Dec 22, 2010, at 20:10 , RichardOnRails wrote:

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710\.

Running this code under SciTE produces, for example:
Getting parms
  Account Number: 123
  Report Period: 456
Showing parms
  @acct_num = 123
  @acct_period = 456

It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names.

I think you are looking for instance_variable_set and instance_variable_get.
I don't really understand all the decisions you made, such as the array of
hashes, to me that implies you want ordered hashes, but are on 1.8 (If you
are in Rails, you have ActiveSupport loaded, and it provides an OrderedHash
class that you can use) since they are ordered in 1.9. To get around that, I
just made it an Array of Structs. Anyway, hopefully you can get out of this
whatever you're trying to do.

class X

  def initialize
    param = Struct.new :human_readable , :ivar
    @rpt_parms = [
      param.new( "Account Number" , "@acct_num" ),
      param.new( "Report Period" , "@acct_period" ),
    ]
  end

  def get_parms
    @rpt_parms.each do |param|
      print "\t#{param.human_readable}: "
      instance_variable_set( param.ivar , gets.to_i ) # don't need to chomp,
to_i will ignore the newline
    end
  end

  def show_parms
    @rpt_parms.each do |param|
      value = instance_variable_get(param.ivar)
      puts "\t#{param.human_readable} = #{value}"
    end
  end

  def run
    puts "Getting parms"
    get_parms
    puts "Showing parms"
    show_parms
  end

end

X.new.run

···

On Wed, Dec 22, 2010 at 10:10 PM, RichardOnRails < RichardDummyMailbox58407@uscomputergurus.com> wrote:

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710\.

Running this code under SciTE produces, for example:
Getting parms
       Account Number: 123
       Report Period: 456
Showing parms
       @acct_num = 123
       @acct_period = 456

It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names. That led me to
using case statements to accept input values and then populate the
instance variables.

Can anyone suggest how I can use the instance variables as targets in
lieu of the case statements? BTW, I want to get this working with
meta-programming. I don't want to use some other approach, such as a
plug-in for getting arguments.

Thanks in Advance,
Richard

I like for someone to help me set the ruby up so that I may use it.

···

--- On Wed, 12/22/10, RichardOnRails <RichardDummyMailbox58407@USComputerGurus.com> wrote:

From: RichardOnRails <RichardDummyMailbox58407@USComputerGurus.com>
Subject: How to DRY code to prompt for parameters
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Date: Wednesday, December 22, 2010, 9:10 PM

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710.

Running this code under SciTE produces, for example:
Getting parms
Account Number: 123
Report Period: 456
Showing parms
@acct_num = 123
@acct_period = 456

It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names. That led me to
using case statements to accept input values and then populate the
instance variables.

Can anyone suggest how I can use the instance variables as targets in
lieu of the case statements? BTW, I want to get this working with
meta-programming. I don't want to use some other approach, such as a
plug-in for getting arguments.

Thanks in Advance,
Richard

http://www.pastie.org/1399777

1) I don't think you need an Array of Hash. Just a Hash.
2) I used "eval" to do what you want

Was it something like this what you wanted?

Abinoam Jr.

···

On Thu, Dec 23, 2010 at 1:40 AM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

On Dec 22, 2010, at 20:10 , RichardOnRails wrote:

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710\.

Running this code under SciTE produces, for example:
Getting parms
Account Number: 123
Report Period: 456
Showing parms
@acct_num = 123
@acct_period = 456

It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names.

It is excessively verbose because you wrote 53 lines when 4 would do:

print "Account Number: "
@acct_num = gets.to_i
print "Report Period: "
@acct_period = gets.to_i

There is nothing wrong with that code. It doesn't have to be 13x more complex to ask the user 2 simple questions.

The definition of DRY is "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system" not "ZOMG I see a 2 line pattern! must kill!"

Please. Do the simplest thing that could possibly work.

P.S. AGAIN with the tabs. I almost didn't write this email at all just because reading your code is too hard.

[Note: parts of this message were removed to make it a legal post.]

> I pasted code to prompt for a couple of parameter-values at
>http://www.pastie.org/1399710\.

> Running this code under SciTE produces, for example:
> Getting parms
> Account Number: 123
> Report Period: 456
> Showing parms
> @acct_num = 123
> @acct_period = 456

> It is excessively verbose because I couldn't figure out how to use
> meta-language to specify the parameter target names. That led me to
> using case statements to accept input values and then populate the
> instance variables.

> Can anyone suggest how I can use the instance variables as targets in
> lieu of the case statements? BTW, I want to get this working with
> meta-programming. I don't want to use some other approach, such as a
> plug-in for getting arguments.

> Thanks in Advance,
> Richard

I think you are looking for instance_variable_set and instance_variable_get.
I don't really understand all the decisions you made, such as the array of
hashes, to me that implies you want ordered hashes, but are on 1.8 (If you
are in Rails, you have ActiveSupport loaded, and it provides an OrderedHash
class that you can use) since they are ordered in 1.9. To get around that, I
just made it an Array of Structs. Anyway, hopefully you can get out of this
whatever you're trying to do.

class X

def initialize
param = Struct.new :human_readable , :ivar
@rpt_parms = [
param.new( "Account Number" , "@acct_num" ),
param.new( "Report Period" , "@acct_period" ),
]
end

def get_parms
@rpt_parms.each do |param|
print "\t#{param.human_readable}: "
instance_variable_set( param.ivar , gets.to_i ) # don't need to chomp,
to_i will ignore the newline
end
end

def show_parms
@rpt_parms.each do |param|
value = instance_variable_get(param.ivar)
puts "\t#{param.human_readable} = #{value}"
end
end

def run
puts "Getting parms"
get_parms
puts "Showing parms"
show_parms
end

end

X.new.run

I think you are looking for instance_variable_set and instance_variable_get.

That's also exactly the thing I needed! Excellent!!

To get around that, I just made it an Array of Structs.

Another responder did what I really wanted but was too stupid to do
is:
  @parms = { "Account Name" => :acct_name,
              "Account Number" => :acct_num
           } # etc.

Thanks very much for your insights.
Best wishes,
Richard

···

On Dec 22, 11:55 pm, Josh Cheek <josh.ch...@gmail.com> wrote:

On Wed, Dec 22, 2010 at 10:10 PM, RichardOnRails < > > > > RichardDummyMailbox58...@uscomputergurus.com> wrote:

you can ask the google for help

···

On Dec 23, 2010, at 09:03 , James Nathan wrote:

I like for someone to help me set the ruby up so that I may use it.

http://www.pastie.org/1399777

1) I don't think you need an Array of Hash. Just a Hash.
2) I used "eval" to do what you want

Was it something like this what you wanted?

Abinoam Jr.

>> I pasted code to prompt for a couple of parameter-values at
>>http://www.pastie.org/1399710\.

>> Running this code under SciTE produces, for example:
>> Getting parms
>> Account Number: 123
>> Report Period: 456
>> Showing parms
>> @acct_num = 123
>> @acct_period = 456

>> It is excessively verbose because I couldn't figure out how to use
>> meta-language to specify the parameter target names.

> It is excessively verbose because you wrote 53 lines when 4 would do:

> print "Account Number: "
> @acct_num = gets.to_i
> print "Report Period: "
> @acct_period = gets.to_i

> There is nothing wrong with that code. It doesn't have to be 13x more complex to ask the user 2 simple questions.

> The definition of DRY is "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system" not "ZOMG I see a 2 line pattern! must kill!"

> Please. Do the simplest thing that could possibly work.

> P.S. AGAIN with the tabs. I almost didn't write this email at all just because reading your code is too hard.

Hi,

1) I don't think you need an Array of Hash. Just a Hash.

You're right. That's much better

2) I used "eval" to do what you want

Was it something like this what you wanted?

I thought about eval, but I didn't know how to apply it to get result
that you did. Your solution is EXACTLY the kind of solution I
imagined but couldn't implement.

Thank you very much,
Richard

···

On Dec 23, 12:00 am, "Abinoam Jr." <abin...@gmail.com> wrote:

On Thu, Dec 23, 2010 at 1:40 AM, Ryan Davis <ryand-r...@zenspider.com> wrote:
> On Dec 22, 2010, at 20:10 , RichardOnRails wrote:

Symbol? Even better.

Mixing some ideas from the Josh code we have...

Remember... as Josh said you shouldn't rely on Hash items order. (this
code does this :confused: )
Hashes are not ordered by nature.

http://www.pastie.org/1400695

···

On Thu, Dec 23, 2010 at 11:10 AM, RichardOnRails <RichardDummyMailbox58407@uscomputergurus.com> wrote:

On Dec 22, 11:55 pm, Josh Cheek <josh.ch...@gmail.com> wrote:

[Note: parts of this message were removed to make it a legal post.]

On Wed, Dec 22, 2010 at 10:10 PM, RichardOnRails < >> >> >> >> RichardDummyMailbox58...@uscomputergurus.com> wrote:
> I pasted code to prompt for a couple of parameter-values at
>http://www.pastie.org/1399710\.

> Running this code under SciTE produces, for example:
> Getting parms
> Account Number: 123
> Report Period: 456
> Showing parms
> @acct_num = 123
> @acct_period = 456

> It is excessively verbose because I couldn't figure out how to use
> meta-language to specify the parameter target names. That led me to
> using case statements to accept input values and then populate the
> instance variables.

> Can anyone suggest how I can use the instance variables as targets in
> lieu of the case statements? BTW, I want to get this working with
> meta-programming. I don't want to use some other approach, such as a
> plug-in for getting arguments.

> Thanks in Advance,
> Richard

I think you are looking for instance_variable_set and instance_variable_get.
I don't really understand all the decisions you made, such as the array of
hashes, to me that implies you want ordered hashes, but are on 1.8 (If you
are in Rails, you have ActiveSupport loaded, and it provides an OrderedHash
class that you can use) since they are ordered in 1.9. To get around that, I
just made it an Array of Structs. Anyway, hopefully you can get out of this
whatever you're trying to do.

class X

def initialize
param = Struct.new :human_readable , :ivar
@rpt_parms = [
param.new( "Account Number" , "@acct_num" ),
param.new( "Report Period" , "@acct_period" ),
]
end

def get_parms
@rpt_parms.each do |param|
print "\t#{param.human_readable}: "
instance_variable_set( param.ivar , gets.to_i ) # don't need to chomp,
to_i will ignore the newline
end
end

def show_parms
@rpt_parms.each do |param|
value = instance_variable_get(param.ivar)
puts "\t#{param.human_readable} = #{value}"
end
end

def run
puts "Getting parms"
get_parms
puts "Showing parms"
show_parms
end

end

X.new.run

I think you are looking for instance_variable_set and instance_variable_get.

That's also exactly the thing I needed! Excellent!!

To get around that, I just made it an Array of Structs.

Another responder did what I really wanted but was too stupid to do
is:
@parms = { "Account Name" => :acct_name,
"Account Number" => :acct_num
} # etc.

Thanks very much for your insights.
Best wishes,
Richard

Symbol? Even better.

Mixing some ideas from the Josh code we have...

Remember... as Josh said you shouldn't rely on Hash items order. (this
code does this :confused: )
Hashes are not ordered by nature.

http://www.pastie.org/1400695

>> [Note: parts of this message were removed to make it a legal post.]

>> > I pasted code to prompt for a couple of parameter-values at
>> >http://www.pastie.org/1399710\.

>> > Running this code under SciTE produces, for example:
>> > Getting parms
>> > Account Number: 123
>> > Report Period: 456
>> > Showing parms
>> > @acct_num = 123
>> > @acct_period = 456

>> > It is excessively verbose because I couldn't figure out how to use
>> > meta-language to specify the parameter target names. That led me to
>> > using case statements to accept input values and then populate the
>> > instance variables.

>> > Can anyone suggest how I can use the instance variables as targets in
>> > lieu of the case statements? BTW, I want to get this working with
>> > meta-programming. I don't want to use some other approach, such as a
>> > plug-in for getting arguments.

>> > Thanks in Advance,
>> > Richard

>> I think you are looking for instance_variable_set and instance_variable_get.
>> I don't really understand all the decisions you made, such as the array of
>> hashes, to me that implies you want ordered hashes, but are on 1.8 (If you
>> are in Rails, you have ActiveSupport loaded, and it provides an OrderedHash
>> class that you can use) since they are ordered in 1.9. To get around that, I
>> just made it an Array of Structs. Anyway, hopefully you can get out of this
>> whatever you're trying to do.

>> class X

>> def initialize
>> param = Struct.new :human_readable , :ivar
>> @rpt_parms = [
>> param.new( "Account Number" , "@acct_num" ),
>> param.new( "Report Period" , "@acct_period" ),
>> ]
>> end

>> def get_parms
>> @rpt_parms.each do |param|
>> print "\t#{param.human_readable}: "
>> instance_variable_set( param.ivar , gets.to_i ) # don't need to chomp,
>> to_i will ignore the newline
>> end
>> end

>> def show_parms
>> @rpt_parms.each do |param|
>> value = instance_variable_get(param.ivar)
>> puts "\t#{param.human_readable} = #{value}"
>> end
>> end

>> def run
>> puts "Getting parms"
>> get_parms
>> puts "Showing parms"
>> show_parms
>> end

>> end

>> X.new.run

>> I think you are looking for instance_variable_set and instance_variable_get.
> That's also exactly the thing I needed! Excellent!!

>> To get around that, I just made it an Array of Structs.
> Another responder did what I really wanted but was too stupid to do
> is:
> @parms = { "Account Name" => :acct_name,
> "Account Number" => :acct_num
> } # etc.

> Thanks very much for your insights.
> Best wishes,
> Richard

Thanks for your additional interest in my question. For my purposes,
the parameter-prompts should be presented in the same order that they
were fed to processor. Also, I want to employ this in future
programs I write, so I also decided to modularize it. So following is
the bottom line, which I present inline here because Pastie barfed
when I tried to post it there. (I don't feel like debugging Pastie:
I've got enough to do!)

Best wishes,
Richard

## Test of new code under SciTE

ruby TestParmHandler.rb

Getting parms
  Account Number: 123
  Report Period: 456
Showing parms
  Account Number = 123
  Report Period = 5456

Exit code: 0

## Test program
# ParmHandlerUser.rb
# K:\_Projects\Ruby\_Ruby_Apps\ParmHandler

require 'ParmHandler.rb'

class ParmHandlerTester
  include ParmHandler
end

phu = ParmHandlerTester.new([
    {"Account Number" => "@acct_num"},
    {"Report Period" => "@acct_period"}
  ])
phu.run

## ParmHandler Module
# ParmHandler.rb
# Copy: K:\_Utilities\ruby186-26_rc2\ruby\lib\ruby\site_ruby
# Original: K:\_Projects\Ruby\_Ruby_Apps\ParmHandler

module ParmHandler
  def initialize rpt_parms
      @rpt_parms = rpt_parms
  end

  def get_parms
    @rpt_parms.each { |param|
  param.each { |parm_name, parm_var|
      print "\t%s: " % parm_name
      STDOUT.flush
      instance_variable_set( parm_var , gets.chomp )
  }
    }
  end

  def show_parms
    @rpt_parms.each { |param|
  param.each { |parm_name, parm_var|
    value = instance_variable_get(parm_var)
    puts "\t%s = %s" % [parm_name, value.to_s]
  }
    }
  end

  def run
    puts "Getting parms"
    get_parms
    puts "Showing parms"
    show_parms
  end
end

···

On Dec 23, 10:05 am, "Abinoam Jr." <abin...@gmail.com> wrote:

On Thu, Dec 23, 2010 at 11:10 AM, RichardOnRails > > <RichardDummyMailbox58...@uscomputergurus.com> wrote:
> On Dec 22, 11:55 pm, Josh Cheek <josh.ch...@gmail.com> wrote:
>> On Wed, Dec 22, 2010 at 10:10 PM, RichardOnRails < > > >> RichardDummyMailbox58...@uscomputergurus.com> wrote: