How to DRY code to prompt for parameters

R

RichardOnRails

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
 
R

Ryan Davis

I pasted code to prompt for a couple of parameter-values at
http://www.pastie.org/1399710.
=20
Running this code under SciTE produces, for example:
Getting parms
Account Number: 123
Report Period: 456
Showing parms
@acct_num =3D 123
@acct_period =3D 456
=20
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 =3D gets.to_i
print "Report Period: "
@acct_period =3D 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.
 
J

Josh Cheek

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

On Wed, Dec 22, 2010 at 10:10 PM, RichardOnRails <
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
 
A

Abinoam Jr.

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.

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

print "Account Number: "
@acct_num =3D gets.to_i
print "Report =A0Period: "
@acct_period =3D gets.to_i

There is nothing wrong with that code. It doesn't have to be 13x more com=
plex to ask the user 2 simple questions.
The definition of DRY is "Every piece of knowledge must have a single, un=
ambiguous, 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 be=
cause reading your code is too hard.
 
R

RichardOnRails

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.









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
 
R

RichardOnRails

[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
 
A

Abinoam Jr.

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 :/ )
Hashes are not ordered by nature.

http://www.pastie.org/1400695

[Note: =A0parts 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
=A0 =A0 =A0 =A0Account Number: 123
=A0 =A0 =A0 =A0Report =A0Period: 456
Showing parms
=A0 =A0 =A0 =A0@acct_num =3D 123
=A0 =A0 =A0 =A0@acct_period =3D 456
It is excessively verbose because I couldn't figure out how to use
meta-language to specify the parameter target names. =A0That 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? =A0BTW, I want to get this working with
meta-programming. =A0I 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 y= ou
are in Rails, you have ActiveSupport loaded, and it provides an OrderedH= ash
class that you can use) since they are ordered in 1.9. To get around tha= t, I
just made it an Array of Structs. Anyway, hopefully you can get out of t= his
whatever you're trying to do.

class X

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

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

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

=A0 def run
=A0 =A0 puts "Getting parms"
=A0 =A0 get_parms
=A0 =A0 puts "Showing parms"
=A0 =A0 show_parms
=A0 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! =A0Excellent!!
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:
=A0@parms =3D { =A0"Account Name" =3D> :acct_name,
=A0 =A0 =A0 =A0 =A0 =A0 =A0"Account Number" =3D> :acct_num
=A0 =A0 =A0 =A0 =A0 } =A0 # etc.

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

RichardOnRails

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 :/ )
Hashes are not ordered by nature.

http://www.pastie.org/1400695

[Note:  parts of this message were removed to make it a legal post.]
@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 (Ifyou
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 ofthis
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
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top