Ruby Not observing DRY principle

HI I am hoping you can give me some guidance. I feel I really am
getting Ruby, far more than I got python I am doing more now in a
couple of weeks than I did with python.

However I just need to get my head around the flow of transactions to
ensure I am not breaking the DRY principle and defeating the purpose
of object orientation.

If this is my proposed flow how can I do it better to be more ruby? I
am happy to do more reading but not always sure what I should
belooking up. I have tried to comment it to make as much sense as
possible.

This is my proposed flow. My main concern is around the option
calculations and selections.

def foo
some function
end

get user input

user input 1
user input 2

pass user variables through foo, each option has different set
variables

??? Should I be using a foreach case statement here or am I someway
missing the
??? the point of object oriented language?
??? Should it be option1.foo, option2.foo etc
option1
foo(set of variables, user input 1)

set of variables will be different for each option

Sets will have same variable types but different values

option 2
foo(set of variables, user input 1)
foo(set of variables, user input 2)
option 3
foo(set of variables, user input 1)
foo(set of variables, user input 2)
option 4
foo(set of variables, user input 1)
foo(set of variables, user input 2)

If result of both tests in an option proves true then output

options.

To_user valid options are
option 1
this is what the results are
option 3
this is what the results are

To_user please choose an option or none to start again.

select case if I list the 5 cases here for a user to select how can

I limit the

selection to valid input only???

If option 1
get some details
send to file dated with date user supplied
send to database

get user more calcs or end?

On Nov 18, 9:22pm, Shadowfirebird [email protected] wrote:

Any ideas appreciated. I just need to understand how to get the flow
better. I notice that if I am thinking something is to hard in Ruby
then I am probably doing it the wrong way. Each tie I do my program I
get better structure just concerned if I am missing the OO point
overall…

On Thursday 18 November 2010 10:40:24 flebber wrote:

On Nov 18, 9:22 pm, Shadowfirebird [email protected] wrote:

Any ideas appreciated. I just need to understand how to get the flow
better. I notice that if I am thinking something is to hard in Ruby
then I am probably doing it the wrong way. Each tie I do my program I
get better structure just concerned if I am missing the OO point
overall…
I don’t really understand what you’re trying to do there, but I think
you
need:

  • An event handler (to intercept user input)
  • Blocks to handle each of your events
  • The process itself (a class representing what the program does)
    ** And, if the user is calling algorithms, then each algorithm belongs
    to it’s
    own class/function. How you call them is a matter of taste (I would
    push a
    hash with algorithm parameters).

I think you need to get your ideas right, then apply ruby and its sugar.

Good luck!

On Nov 18, 10:00pm, Arturo G. [email protected] wrote:

  • An event handler (to intercept user input)
  • Blocks to handle each of your events
  • The process itself (a class representing what the program does)
    ** And, if the user is calling algorithms, then each algorithm belongs to it’s
    own class/function. How you call them is a matter of taste (I would push a
    hash with algorithm parameters).

I think you need to get your ideas right, then apply ruby and its sugar.

Good luck!

To me thats where I am tripping up, in my program I define a function
but don’t seem to need a class or would it be simply that my function
I am calling is my class.

Really interested to now what type of case statement or for each
satement you would use with a block like below.

??? Should I be using a foreach case statement here or am I someway
missing the
??? the point of object oriented language?
??? Should it be option1.foo, option2.foo etc
option1
foo(set of variables, user input 1)
# set of variables will be different for each option
# Sets will have same variable types but different values
option 2
foo(set of variables, user input 1)
foo(set of variables, user input 2)
option 3
foo(set of variables, user input 1)
foo(set of variables, user input 2)
option 4
foo(set of variables, user input 1)
foo(set of variables, user input 2)

If result of both tests in an option proves true then output

options.

I don’t really understand what you’re trying to do there, but I
think you need:

  • An event handler (to intercept user input)
  • Blocks to handle each of your events
  • The process itself (a class representing what the program does)
    ** And, if the user is calling algorithms, then each algorithm
    belongs to it’s own class/function. How you call them is a matter
    of taste (I would push a hash with algorithm parameters).

That is an example of the strategy pattern!

http://www.c2.com/cgi/wiki?StrategyPattern

option 4
foo(set of variables, user input 1)
foo(set of variables, user input 2)

Is this sort of thing what you mean?

The main loop

def main
loop do
puts “Please choose an option:”
puts " [1] Option1"
puts " [2] Option2"
puts " [3] Option3"
opt = nil

  # A primitive event handler
  case gets.to_i
  when 1
     opt = Option1.new
  when 2
     opt = Option2.new
  when 3
     opt = Option3.new
  end

  # Check if a valid option was entered
  if opt
     opt.run
  else
     puts "Error: please enter valid option."
  end

end
end

Run the program

main

You also need to define

The first option. I wish I had a better name!

class Option1

get some details

send to file dated with date user supplied

send to database

def run
end

end

Flebber, the benefit of using objects to represent your options, rather
than just functions, is that you may then apply the various object
oriented techniques.

E.g. TemplateMethod could remove duplicate code from
similar Options

http://www.c2.com/cgi/wiki?TemplateMethod

However, using a strict object oriented approach can be pretty
heavy-weight!

Johnny

On Thursday 18 November 2010 11:15:15 flebber wrote:

Really interested to now what type of case statement or for each
satement you would use with a block like below.
Sorry. I don’t see where a foreach falls in there. If your options are
known, then you either a hash or a case would suffice. But again, it
has
nothing to do with ruby.

event_handler = { :event => lambda { action } }

or

case event
when event
<< do something >>

I would prefer number 2 if you have 4 options, to be honest…

It appears that my mail client is having trouble – hence the blank
message bodies. Sorry about that.

Flebber, if you have a simple application and aren’t coding to learn
about OOP, it may be that you simply don’t need classes. In Ruby,
they are optional.

You should think of classes as a way of wrapping functionality and
data together. You’ve not told us anything about your data, or how
complex foo() is, so I’m not sure we can give you more concrete
suggestions. But if you start thinking about how the data needs to
be organised, and what operations the data needs to be able to perform
on itself, then either some classes will “pop out” – or they won’t,
and you’ll know that this program does not need to be OOP.

With regard to your option selection block, I would personally put
that functionality into foo, and just pass foo a “mode” variable, so:

loop do
mode, data = getinput()
break if (mode == “quit”)

foo(mode, data)

end

I’m not sure why your pseudocode asks for input twice and then runs
foo() twice, but presumably there is a good reason.

Likewise, we don’t know whether you plan to gather input using a GUI
(which would involve an event-driven approach) or at the command line,
for instance (which would allow much simpler code).

On Nov 18, 11:45pm, shadowfirebird [email protected] wrote:

suggestions. But if you start thinking about how the data needs to

foo(mode, data)
end

I’m not sure why your pseudocode asks for input twice and then runs
foo() twice, but presumably there is a good reason.

Likewise, we don’t know whether you plan to gather input using a GUI
(which would involve an event-driven approach) or at the command line,
for instance (which would allow much simpler code).

  # Check if a valid option was entered
  if opt
     opt.run
  else
     puts "Error: please enter valid option."
  end

end
end

Yes but this is how initially I started to write my code but then had
the thought that since my calculations weren’t computer intensive. So
I thought why not calculate all options first and show what valid
options exist to the user rather than looping around the options
trying to find a valid option. Is this a good way to go.

I’m not sure why your pseudocode asks for input twice and then runs
foo() twice, but presumably there is a good reason.

Likewise, we don’t know whether you plan to gather input using a GUI
(which would involve an event-driven approach) or at the command line,
for instance (which would allow much simpler code).

I ask after the program has identified there is a valid option and the
user wants to select it, it is valid data but only names and
identifiers that will be recorded in a database not relevant to
whether the calculation is valid.

i will be using a command line solution. My calculations aren’t
complex they simply pass through a small formula and check whether a
ratio resolves to true. If both true then its a valid option the user
can choose.

Yes but this is how initially I started to write my code but then had
the thought that since my calculations weren’t computer intensive. So
I thought why not calculate all options first and show what valid
options exist to the user rather than looping around the options
trying to find a valid option. Is this a good way to go.

That’s entirely up to you.

However, I think most mail clients have a send button - even when you
haven’t entered yet an email address!

John

On Nov 19, 9:22am, John M. [email protected] wrote:

John

Can a case statement return multiple correct cases?

Can a case statement return multiple correct cases?

nope.

But this will, and it’s no less compact than a case statement IMO:

wins = []
wins << 1 if (a > 3)
wnis << 2 if (a > 5)
wins << 3 if (a < 7)
wins << 4 if (a < 3)

For a = 4, wins should be [1,3]. Hopefully you get the idea.

nope.

On Nov 19, 9:01pm, Shadowfirebird [email protected] wrote:

wnis << 2 if (a > 5)
wins << 3 if (a < 7)
wins << 4 if (a < 3)

For a = 4, wins should be [1,3]. Hopefully you get the idea.


What a tangled web we weave / Go 'round with circumstance / Someone show me
how to tell / The dancer from the dance…

I like your example so I started reading.

if for each wins in your example their was two conditions I could then
chain them together with an and. Awesome thanks.

So following your example where wins = [1,3] ( still not sure why ruby
doesn’t have a multiple case select) can I use “and” “or”

If wins = 1 puts “for option 1 x = A_value and y = B_value”
and or
If wins = 2 puts “for option 2 x = A_value and y = B_value”
and or
If wins = 3 puts “for option 3 x = A_value and y = B_value”
and or
If wins = 4 puts “for option 2 x = A_value and y = B_value”
else puts " There were no valid options"

On Nov 19, 10:01pm, flebber [email protected] wrote:

But this will, and it’s no less compact than a case statement IMO:
What a tangled web we weave / Go 'round with circumstance / Someone show me
If wins = 1 puts “for option 1 x = A_value and y = B_value”
and or
If wins = 2 puts “for option 2 x = A_value and y = B_value”
and or
If wins = 3 puts “for option 3 x = A_value and y = B_value”
and or
If wins = 4 puts “for option 2 x = A_value and y = B_value”
else puts " There were no valid options"

I apologise. Combination of learning and tired. I woke up in the
middle of the night and went while statement or case statement. Silly
me found this this morning.

def foo
some function
end

get user input

user input 1
user input 2

foo(user input, option number)

As you are (so far) writing in a procedural style, I think foo looks
more natural than user_input.foo. Your first procedure (which might be
foo in this case) needs to route according to the selected option.

The basic rule of all programming, not just OO, is to create a set of
methods - some clearly acting as controllers , and others carrying out
tasks - that divide the problem up into discrete encapsulated ‘black
box’ units. So just avoid jumbling up too much functionality in any
given
method.