Module using object defined outside of method?


(Leam Hall) #1

I have a class Dice with a method "roll_1". It gives a result between 1-6.

···

###
class Dice
   def roll_1
     rand(1..6)
   end
end
###

The module CharacterTools uses Dice.roll_1.

###
module CharacterTools

  require 'dice'
  dice = Dice.new

  def roll_1
    dice = Dice.new
    dice.roll_1
  end
end
###

"dice" is declared twice, outside and inside the roll_1 method definition. I am trying to figure out how to instantiate one "dice" object outside of the method that calls it. For each program run there are lots of calls to roll_1. It seems better to create one Dice object and call it a lot of times.

CharacterTools itself is mixed in with other classes.

This is a personal learning exercise so pointers to good tutorials are better than outright answers. Even good Google search terms would be better.

Thanks!

Leam


(Andy Jones) #2

###
module CharacterTools

  require 'dice'
  dice = Dice.new

  def roll_1
    dice = Dice.new
    dice.roll_1
  end
end
###

The simple answer is that the first declaration of dice isn't doing anything. You can leave it out.

Since this is a mixin, you could always have it declare a @dice attribute that you can reuse later. That would look something like this:

···

###
require 'dice' # really this should be at the top of the file?

module CharacterTools

  def dice
    @dice ||= Dice.new
  end

  def roll_1
    dice.roll_1
  end

end
###

The dice method is a slightly sneaky trick: if @dice is already defined then it returns it; otherwise it defines it and returns it. So you can use dice exactly as if it was an automagically defined @dice attribute.

Hope that helps...

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>


(Saumya jeet) #3

I can recommend you this book.
<https://www.amazon.com/dp/1934356476/?tag=stackoverfl08-20>
It has best explanation about Inheritance and objects, metaprogramming,
callbacks and refactoring

···

On 13 February 2018 at 17:15, Leam Hall <leamhall@gmail.com> wrote:

I have a class Dice with a method "roll_1". It gives a result between 1-6.

###
class Dice
  def roll_1
    rand(1..6)
  end
end
###

The module CharacterTools uses Dice.roll_1.

###
module CharacterTools

require 'dice'
dice = Dice.new

def roll_1
   dice = Dice.new
   dice.roll_1
end
end
###

"dice" is declared twice, outside and inside the roll_1 method definition.
I am trying to figure out how to instantiate one "dice" object outside of
the method that calls it. For each program run there are lots of calls to
roll_1. It seems better to create one Dice object and call it a lot of
times.

CharacterTools itself is mixed in with other classes.

This is a personal learning exercise so pointers to good tutorials are
better than outright answers. Even good Google search terms would be better.

Thanks!

Leam

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
2nd Year UG
Electrical Engineering
IIEST Shibpur


(Leam Hall) #4

Andy, thanks! I've tried this on my Windows box and need to puzzle it
out a bit more. Your solution will probably work as soon as I
understand it. :slight_smile:

Leam

···

On Tue, Feb 13, 2018 at 7:13 AM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

###
module CharacterTools

  require 'dice'
  dice = Dice.new

  def roll_1
    dice = Dice.new
    dice.roll_1
  end
end
###

<<<<<<<<

The simple answer is that the first declaration of dice isn't doing anything. You can leave it out.

Since this is a mixin, you could always have it declare a @dice attribute that you can reuse later. That would look something like this:

###
require 'dice' # really this should be at the top of the file?

module CharacterTools

  def dice
    @dice ||= Dice.new
  end

  def roll_1
    dice.roll_1
  end

end
###

The dice method is a slightly sneaky trick: if @dice is already defined then it returns it; otherwise it defines it and returns it. So you can use dice exactly as if it was an automagically defined @dice attribute.

Hope that helps...


(Leam Hall) #5

Saumya, I have a copy of that but when I tried to read it a couple
years ago it was over my head. I am working through a few books and
trying to learn more Ruby. Sometimes I just get stuck on a simple
problem.

Thanks!

Leam

···

On Tue, Feb 13, 2018 at 7:21 AM, Saumya jeet <promptc3.0@gmail.com> wrote:

I can recommend you this book.
It has best explanation about Inheritance and objects, metaprogramming,
callbacks and refactoring


(Leam Hall) #6

This is all one file. It gives a number for the first puts but an
"undefined local variable or method" for the second.

···

On Tue, Feb 13, 2018 at 8:23 AM, leam hall <leamhall@gmail.com> wrote:

On Tue, Feb 13, 2018 at 7:13 AM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

###
module CharacterTools

  require 'dice'
  dice = Dice.new

  def roll_1
    dice = Dice.new
    dice.roll_1
  end
end
###

<<<<<<<<

The simple answer is that the first declaration of dice isn't doing anything. You can leave it out.

Since this is a mixin, you could always have it declare a @dice attribute that you can reuse later. That would look something like this:

###
require 'dice' # really this should be at the top of the file?

module CharacterTools

  def dice
    @dice ||= Dice.new
  end

  def roll_1
    dice.roll_1
  end

end
###

The dice method is a slightly sneaky trick: if @dice is already defined then it returns it; otherwise it defines it and returns it. So you can use dice exactly as if it was an automagically defined @dice attribute.

Hope that helps...

Andy, thanks! I've tried this on my Windows box and need to puzzle it
out a bit more. Your solution will probably work as soon as I
understand it. :slight_smile:

Leam

####
class Dice < Object
  def roll_1
    rand(1..6)
  end
end

module CT
  def dice
    @dice ||= Dice.new
  end

  def roll_1
    dice.roll_1
  end
end

dice = Dice.new
puts dice.roll_1
puts roll_1

###

Thoughts?

Leam


(Andy Jones) #7

This is all one file. It gives a number for the first puts but an "undefined local variable or method" for the second.

####
class Dice < Object
  def roll_1
    rand(1..6)
  end
end

module CT
  def dice
    @dice ||= Dice.new
  end

  def roll_1
    dice.roll_1
  end
end

dice = Dice.new
puts dice.roll_1
puts roll_1

###

I would expect that. When ruby sees "puts roll_1" it's looking for a roll_1 method and there isn't one.

There is a roll_1 method in the dice object, so "puts dice.roll_1" works fine. There is a roll_1 method in the CT module, but you're not using that; you've defined it, but you're not using it.

CT is going to be used as a mixin, and if you use it that way, I'm guessing that will work:

···

###
class Foo
  include CT

  def bar
    roll_1
  end

end

Foo.new.bar # => calls Foo.bar which calls CT.roll_1 which calls Dice.roll_1
###

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>


(Steve Turczyn) #8

If you don't actually need to store any state information (e.g. "what was the last roll of that die?") then you're wasting your time creating a class where a module will work fine.

module Dice
  def self.roll_1
    rand(1..6)
  end
end

Then just reference it where you need it with...

Dice.roll_1

If you really want to use a class, you can stick to your original code but create a disposable instance... something that only exists for the moment it's needed...

Dice.new.roll_1

...but this is only really useful when the "roll_1" method needs to reference other methods and you therefore need to store some state information to complete the task.

So (again) you only need a class object if you need to keep track of states/values.

···

On Tue, Feb 13, 2018, at 11:45 AM, Leam Hall wrote:

I have a class Dice with a method "roll_1". It gives a result between 1-6.

###
class Dice
   def roll_1
     rand(1..6)
   end
end
###

The module CharacterTools uses Dice.roll_1.

###
module CharacterTools

  require 'dice'
  dice = Dice.new

  def roll_1
    dice = Dice.new
    dice.roll_1
  end
end
###

"dice" is declared twice, outside and inside the roll_1 method
definition. I am trying to figure out how to instantiate one "dice"
object outside of the method that calls it. For each program run there
are lots of calls to roll_1. It seems better to create one Dice object
and call it a lot of times.

CharacterTools itself is mixed in with other classes.

This is a personal learning exercise so pointers to good tutorials are
better than outright answers. Even good Google search terms would be better.

Thanks!

Leam

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>


(Leam Hall) #9

Yes, it works. Thanks!

Leam

···

On 02/13/2018 07:13 AM, Andy Jones wrote:

###
module CharacterTools

   require 'dice'
   dice = Dice.new

   def roll_1
     dice = Dice.new
     dice.roll_1
   end
end
###

<<<<<<<<

The simple answer is that the first declaration of dice isn't doing anything. You can leave it out.

Since this is a mixin, you could always have it declare a @dice attribute that you can reuse later. That would look something like this:

###
require 'dice' # really this should be at the top of the file?

module CharacterTools

   def dice
     @dice ||= Dice.new
   end

   def roll_1
     dice.roll_1
   end

end
###

The dice method is a slightly sneaky trick: if @dice is already defined then it returns it; otherwise it defines it and returns it. So you can use dice exactly as if it was an automagically defined @dice attribute.

Hope that helps...


(Leam Hall) #10

Steve, the roll methods are currently in a module for a specific task. I am moving them to a general task class/module and wanted to play with classes more. The rolls don't need to maintain state, but there are other rolls that call the base.

This is mostly me figuring out OOP as I stumble along. :slight_smile:

Thanks!

Leam

···

On 02/13/2018 10:00 AM, Steve Turczyn wrote:

If you don't actually need to store any state information (e.g. "what was the last roll of that die?") then you're wasting your time creating a class where a module will work fine.

module Dice
   def self.roll_1
     rand(1..6)
   end
end

Then just reference it where you need it with...

Dice.roll_1

If you really want to use a class, you can stick to your original code but create a disposable instance... something that only exists for the moment it's needed...

Dice.new.roll_1

...but this is only really useful when the "roll_1" method needs to reference other methods and you therefore need to store some state information to complete the task.

So (again) you only need a class object if you need to keep track of states/values.