Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #4106 > unrolled thread

Question regarding interaction between modules and classes

Started byGeometric Patterns <geometric.patterns@gmail.com>
First post2011-05-07 22:02 -0500
Last post2011-05-07 22:34 -0500
Articles 3 — 3 participants

Back to article view | Back to comp.lang.ruby


Contents

  Question regarding interaction between modules and classes Geometric Patterns <geometric.patterns@gmail.com> - 2011-05-07 22:02 -0500
    Re: Question regarding interaction between modules and classes Josh Cheek <josh.cheek@gmail.com> - 2011-05-07 22:31 -0500
    Re: Question regarding interaction between modules and classes 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-07 22:34 -0500

#4106 — Question regarding interaction between modules and classes

FromGeometric Patterns <geometric.patterns@gmail.com>
Date2011-05-07 22:02 -0500
SubjectQuestion regarding interaction between modules and classes
Message-ID<fb5b1151925c37ab1b0160d82a746ea4@ruby-forum.com>
Hi,

In the code below, is there a way to learn @foo from $bar_one
using $bar_two?

Many thanks in advance!!


----------------

#!/usr/bin/ruby -w

module Foo
   def setup
      @foo = self.object_id
   end
   def foo
      return @foo
   end
end

class Bar
   include Foo
end

$bar_one = Bar.new
$bar_one.setup
p $bar_one.foo  # => 2148224640

$bar_two = Bar.new
p $bar_two.foo  # => warning: instance variable @foo not initialized

----------------

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

[toc] | [next] | [standalone]


#4108

FromJosh Cheek <josh.cheek@gmail.com>
Date2011-05-07 22:31 -0500
Message-ID<BANLkTikzDEUBP7VqU=xtvFbuGCSPN4hpQQ@mail.gmail.com>
In reply to#4106
[Note:  parts of this message were removed to make it a legal post.]

On Sat, May 7, 2011 at 10:02 PM, Geometric Patterns <
geometric.patterns@gmail.com> wrote:

> Hi,
>
> In the code below, is there a way to learn @foo from $bar_one
> using $bar_two?
>
> Many thanks in advance!!
>
>
> ----------------
>
> #!/usr/bin/ruby -w
>
> module Foo
>   def setup
>      @foo = self.object_id
>   end
>   def foo
>      return @foo
>   end
> end
>
> class Bar
>   include Foo
> end
>
> $bar_one = Bar.new
> $bar_one.setup
> p $bar_one.foo  # => 2148224640
>
> $bar_two = Bar.new
> p $bar_two.foo  # => warning: instance variable @foo not initialized
>
> ----------------
>
> --
> Posted via http://www.ruby-forum.com/.
>
>
Hmm. Okay, first a bunch of thoughts, then some potential solutions.

1. Variables that begin with the $ sigil are global. For a local variable,
no sigil necessary:
  module Foo
    def setup
      @foo = self.object_id
    end
    def foo
      return @foo
    end
  end
  class Bar
    include Foo
  end
  bar_one = Bar.new
  bar_one.setup
  bar_one.foo  # => 2151888860

2. There is an implicit setup method called "initialize", it is unusual to
me that you have your own, which you invoke explicitly.
  module Foo
    def initialize
      @foo = self.object_id
    end
    def foo
      return @foo
    end
  end
  class Bar
    include Foo
  end
  Bar.new.foo # => 2151889080

3. When invoking a method on the current object, self is not necessary
  module Foo
    def initialize
      @foo = object_id
    end
    def foo
      return @foo
    end
  end
  class Bar
    include Foo
  end
  Bar.new.foo # => 2151889080

4. The last line of a method is automatically returned, no explicit "return"
is necessary
  module Foo
    def initialize
      @foo = object_id
    end
    def foo
      @foo
    end
  end
  class Bar
    include Foo
  end
  Bar.new.foo # => 2151889100

5. When you have a method which returns an instance variable of the same
name, that is a less efficient version of  "attr_reader :ivar_name"
  module Foo
    def initialize
      @foo = object_id
    end
    attr_reader :foo
  end
  class Bar
    include Foo
  end
  Bar.new.foo # => 2151889260

---

Okay, now that we're here, I assume you want to know if bar_two can know
bar_one's foo
  bar_one = Bar.new
  bar_two = Bar.new
  bar_one.foo # => 2151886760
  bar_two.foo # => 2151886740

But it is unclear, because you were initially using global variables, which
breaks scope, allowing a method like
  module Foo
    def initialize
      @foo = object_id
    end
    attr_reader :foo
    def bar_ones_foo
      $bar_one.foo
    end
  end
  class Bar
    include Foo
  end
  $bar_one = Bar.new
  $bar_two = Bar.new
  $bar_one.foo # => 2151884160
  $bar_two.foo # => 2151884140
  $bar_two.bar_ones_foo # => 2151884160

Which, seems very strange to me, and doesn't work if you actually meant to
have local variables (globals are considered a code smell).

Alternatively, you could have been asking whether they could share the @foo
ivar, in which case the answer is no, that ivar is unique to whichever
object the method is being called on. However, you could use a class
variable

  module Foo
    def initialize
      @@foo = object_id
    end
    def foo
      @@foo
    end
  end
  class Bar
    include Foo
  end
  bar_one = Bar.new
  bar_one.foo # => 2151892400
  bar_two = Bar.new
  bar_two.foo # => 2151891900
  bar_one.foo # => 2151891900
  Foo.class_variables # => [:@@foo]

Or, more commonly, an instance variable either on Foo or on Bar
  module Foo
    class << self
      attr_accessor :foo
    end
    def initialize
      Foo.foo = object_id
    end
    def foo
      Foo.foo
    end
  end
  class Bar
    include Foo
  end
  bar_one = Bar.new
  bar_one.foo # => 2151891940
  bar_two = Bar.new
  bar_two.foo # => 2151891440
  bar_one.foo # => 2151891440

Although, your wording is pretty vague, this would technically satisfy the
request
  module Foo
    def initialize
      @foo = object_id
    end
    attr_reader :foo
    def foo_of(other)
      other.foo
    end
  end
  class Bar
    include Foo
  end
  bar_one = Bar.new
  bar_two = Bar.new
  bar_one.foo # => 2151894400
  bar_two.foo # => 2151894380
  bar_two.foo_of bar_one # => 2151894400


So anyway, hopefully something in there addresses what you are asking. If
not, you'll have to give more feedback (ie an interface to access this
information).

[toc] | [prev] | [next] | [standalone]


#4109

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-05-07 22:34 -0500
Message-ID<db6fc5702c988fbc83bf9bac48019399@ruby-forum.com>
In reply to#4106
Geometric Patterns wrote in post #997317:
> Hi,

Don't EVER use global variables($).


module Foo
   def setup
      id = self.object_id
      puts id

      self.class.class_eval do
         @foo=  id

         def self.foo
            @foo
         end
      end
  end

   def foo
      return self.class.foo
   end
end

class Bar
   include Foo
end

bar_one = Bar.new
bar_one.setup
p bar_one.foo  # => 2148224640

bar_two = Bar.new
p bar_two.foo  # => warning: instance variable @foo not initialized

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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.ruby


csiph-web