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?

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.

···

--
Posted via http://www.ruby-forum.com/\.

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 Nov 18, 9:22 pm, Shadowfirebird <shadowfireb...@gmail.com> wrote:

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 Thursday 18 November 2010 10:40:24 flebber wrote:

On Nov 18, 9:22 pm, Shadowfirebird <shadowfireb...@gmail.com> 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.....

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.

···

On Nov 18, 10:00 pm, Arturo Garcia <arturo.g.art...@gmail.com> wrote:

On Thursday 18 November 2010 10:40:24 flebber wrote:> On Nov 18, 9:22 pm, Shadowfirebird <shadowfireb...@gmail.com> 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!

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....

···

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.

> 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

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)

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

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).

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).

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

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.

···

On Nov 18, 11:45 pm, shadowfirebird <shadowfireb...@gmail.com> wrote:

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

Can a case statement return multiple correct cases?

···

On Nov 19, 9:22 am, John Morrice <sp...@killersmurf.com> wrote:

> 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

nope.

···

On Fri, 2010-11-19 at 15:45 +0900, flebber wrote:

On Nov 19, 9:22 am, John Morrice <sp...@killersmurf.com> wrote:
> > 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

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.

···

--
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, 9:01 pm, Shadowfirebird <shadowfireb...@gmail.com> wrote:

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

> 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.

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

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.

···

On Nov 19, 10:01 pm, flebber <flebber.c...@gmail.com> wrote:

On Nov 19, 9:01 pm, Shadowfirebird <shadowfireb...@gmail.com> wrote:

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

> > 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.

> --
> 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"