Modules as namespaces

I'm in the middle of packaging up a project as a gem, and in the process I
decided to enclose every file in a module, to namespace it. I ran into a
fairly surprising issue, which makes me wonder if ruby couldn't use a
"namespace" concept distinct from the class/module system:

···

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

Hi
I think you always have to require a module. Dont know if there are other
possibilities

···

Am 06.01.2016 02:43 schrieb "Martin DeMello" <martindemello@gmail.com>:

I'm in the middle of packaging up a project as a gem, and in the process I
decided to enclose every file in a module, to namespace it. I ran into a
fairly surprising issue, which makes me wonder if ruby couldn't use a
"namespace" concept distinct from the class/module system:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

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

Martin DeMello <martindemello@gmail.com> writes:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

This works, because the method #helper_fn is defined implicitely as an
instance method in the Object class:

irb(main):001:0> def help_fn
irb(main):002:1> puts "Hello from helper"
irb(main):003:1> end
=> :help_fn
irb(main):004:0> method(:help_fn)
=> #<Method: Object#help_fn>

That makes it available everywhere. To make your second example work,
you need to do one of the following:

1)

  module Namespace
    def self.helper_fn
      puts "Hello from helper"
    end
    class Foo
      def self.bar
        Namespace.helper_fn
      end
    end
  end

This defines Namespace.helper_fn as a module-level function on the
Namespace module, in contrast to the definition as an instance method as
your second example contained it. As such, it needs to be called with
the Namespace module as the receiver then in Namespace::Foo.bar.

2)

  module Namespace
    def helper_fn
      puts "Hello from helper"
    end
    class Foo
      extend Namespace
      def self.bar
        helper_fn
      end
    end
  end

This keeps the definition of "helper_fn" as an instance method in the
Namespace module, but by means of the #extend method the Namespace
module is injected into the method resolution chain of the
Namespace::Foo class object itself.

There’s also a third option, that however requires more coding effort:

  module Namespace
    module Helpers
      def helper_fn
        puts "Hello from helper"
      end
      module_function :helper_fn
    end
    class Foo
      extend Helpers
      def self.bar
        helper_fn
      end
    end
  end

This extracts the helper function into its own module, and utilises the
#module_function method to make it both a module-level and
instance-level method of the Helpers module. In Namespace::Foo you can
then choose between using #extend and calling "helper_fn" without
explicit receiver (as shown above) or using
Namespace::Helpers.helper_fn. Both ways work simultaneously.

I’m sure there are even more ways to solve the problem, but I don’t
think there’s a problem with Rubys namespacing mechanism here. The
concept of instance methods on modules being only available when you mix
in the module is just a different way to do things.

Ruby makes no difference between a module used for namespacing and one
used for mixin purposes only. It is possible to even intermix both
concepts (Ruby’s own Math module for example does this), which can be
used for creating procedural-like APIs where full OO capability is not
required.

Greetings
Marvin

···

--
#!/sbin/quintus
Blog: http://www.guelkerdev.de

GnuPG key: F1D8799FBCC8BC4F

If we include a class inside a module, then none of the methods inside
module will be visible inside class

···

On Jan 6, 2016 7:13 AM, "Martin DeMello" <martindemello@gmail.com> wrote:

I'm in the middle of packaging up a project as a gem, and in the process I
decided to enclose every file in a module, to namespace it. I ran into a
fairly surprising issue, which makes me wonder if ruby couldn't use a
"namespace" concept distinct from the class/module system:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

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

yes; once I thought about it a bit I realised what was going on. my point
is that it goes against the grain of using modules as the ruby way to do
namespaces. all that really happens is that Foo gets the fully qualified
name Namespace::Foo (this stackoverflow post explains it nicely:

).

martin

···

On Tue, Jan 5, 2016 at 10:53 PM, A Berger <aberger7890@gmail.com> wrote:

Hi
I think you always have to require a module. Dont know if there are other
possibilities
Am 06.01.2016 02:43 schrieb "Martin DeMello" <martindemello@gmail.com>:

I'm in the middle of packaging up a project as a gem, and in the process
I decided to enclose every file in a module, to namespace it. I ran into a
fairly surprising issue, which makes me wonder if ruby couldn't use a
"namespace" concept distinct from the class/module system:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

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

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

I ended up doing

class Foo
  include Namespace

  ...
end

with a comment explaining why I was doing it.

The actual commit is here, in case anyone has suggestions:

martin

···

On Wed, Jan 6, 2016 at 1:45 AM, Jorge Colon <2upmedia@gmail.com> wrote:

If you really need to you could do:

module Namespace

def self.helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    Namespace.helper_fn
  end
end

end

Namespace::Foo.bar

Best,

Jorge Colon

Senior Software Architect/Technical Advisor/Owner

2UP Media
c: 407.489.2677
jorge@2upmedia.com
www.2upmedia.com

"I help software companies and startup founders get more sleep while
improving their software product for their customers"

LinkedIn <http://www.linkedin.com/in/2upmedia&gt;

On Jan 6, 2016, at 4:18 AM, Martin DeMello <martindemello@gmail.com> > wrote:

yes; once I thought about it a bit I realised what was going on. my point
is that it goes against the grain of using modules as the ruby way to do
namespaces. all that really happens is that Foo gets the fully qualified
name Namespace::Foo (this stackoverflow post explains it nicely:
Ruby Classes within Classes (or Modules within Modules) - Stack Overflow
).

martin

On Tue, Jan 5, 2016 at 10:53 PM, A Berger <aberger7890@gmail.com> wrote:

Hi
I think you always have to require a module. Dont know if there are other
possibilities
Am 06.01.2016 02:43 schrieb "Martin DeMello" <martindemello@gmail.com>:

I'm in the middle of packaging up a project as a gem, and in the process
I decided to enclose every file in a module, to namespace it. I ran into a
fairly surprising issue, which makes me wonder if ruby couldn't use a
"namespace" concept distinct from the class/module system:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

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

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

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

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

If you really need to you could do:

module Namespace

def self.helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    Namespace.helper_fn
  end
end

end

Namespace::Foo.bar

Best,

Jorge Colon

Senior Software Architect/Technical Advisor/Owner

2UP Media
c: 407.489.2677
jorge@2upmedia.com
www.2upmedia.com

"I help software companies and startup founders get more sleep while improving their software product for their customers"

LinkedIn

···

On Jan 6, 2016, at 4:18 AM, Martin DeMello <martindemello@gmail.com> wrote:

yes; once I thought about it a bit I realised what was going on. my point is that it goes against the grain of using modules as the ruby way to do namespaces. all that really happens is that Foo gets the fully qualified name Namespace::Foo (this stackoverflow post explains it nicely: Ruby Classes within Classes (or Modules within Modules) - Stack Overflow).

martin

On Tue, Jan 5, 2016 at 10:53 PM, A Berger <aberger7890@gmail.com> wrote:
Hi
I think you always have to require a module. Dont know if there are other possibilities
Am 06.01.2016 02:43 schrieb "Martin DeMello" <martindemello@gmail.com>:

I'm in the middle of packaging up a project as a gem, and in the process I decided to enclose every file in a module, to namespace it. I ran into a fairly surprising issue, which makes me wonder if ruby couldn't use a "namespace" concept distinct from the class/module system:

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

before.rb, working:

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

Foo.bar

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

after.rb, not working:

module Namespace

def helper_fn
  puts "Hello from helper"
end

class Foo
  def self.bar
    helper_fn
  end
end

end # module Namespace

Namespace::Foo.bar

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

martin

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

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

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

I ended up doing

class Foo
   include Namespace

   ...
end

with a comment explaining why I was doing it.

The actual commit is here, in case anyone has suggestions:

https://github.com/martindemello/pangrid/commit/1fe6a2d658931ca3eeb08095ab00bfd3d6e40ea1

martin

This is also a software engineering problem, isn't it?

The code should show what the relationship is between the modules, classes, (functions), etc.

Presumably, you have a helper function because it's a miscellaneous piece of code required by different (other) modules and classes. Why would you want to include the helper function in a module together with the class that's using it? It's hard to tell from the admittedly small example, but in the example, it would be more natural to include the helper function as a class function, right? Or have a module of helper functions as a sibling to the module including the using classes (and perhaps modules)?

In terms of organisation, I would prefer a module of helper function(s) to be a sibling of the top level of the module(s) that need it.

         TopModule
   --------|-------
   > >
ModHelpers Mod
               ----|----
               > >
            MoreMods Class2 (uses ModHelpers.funky)

···

On 06.01.2016 10:55, Martin DeMello wrote:

On Wed, Jan 6, 2016 at 1:45 AM, Jorge Colon <2upmedia@gmail.com > <mailto:2upmedia@gmail.com>> wrote:

    If you really need to you could do:

    module Namespace

    def self.helper_fn
       puts "Hello from helper"
    end

    class Foo
       def self.bar
         Namespace.helper_fn
       end
    end

    end

    Namespace::Foo.bar

    Best,

    Jorge Colon

    Senior Software Architect/Technical Advisor/Owner

    2UP Media
    c: 407.489.2677 <tel:407.489.2677>
    jorge@2upmedia.com <mailto:jorge@2upmedia.com>
    www.2upmedia.com <http://www.2upmedia.com>

    "I help software companies and startup founders get more sleep while
    improving their software product for their customers"

    LinkedIn <http://www.linkedin.com/in/2upmedia&gt;

    On Jan 6, 2016, at 4:18 AM, Martin DeMello <martindemello@gmail.com > <mailto:martindemello@gmail.com>> wrote:

    yes; once I thought about it a bit I realised what was going on.
    my point is that it goes against the grain of using modules as the
    ruby way to do namespaces. all that really happens is that Foo
    gets the fully qualified name Namespace::Foo (this stackoverflow
    post explains it nicely:
    Ruby Classes within Classes (or Modules within Modules) - Stack Overflow).

    martin

    On Tue, Jan 5, 2016 at 10:53 PM, A Berger <aberger7890@gmail.com >> <mailto:aberger7890@gmail.com>> wrote:

        Hi
        I think you always have to require a module. Dont know if
        there are other possibilities

        Am 06.01.2016 02:43 schrieb "Martin DeMello"
        <martindemello@gmail.com <mailto:martindemello@gmail.com>>:

            I'm in the middle of packaging up a project as a gem, and
            in the process I decided to enclose every file in a
            module, to namespace it. I ran into a fairly surprising
            issue, which makes me wonder if ruby couldn't use a
            "namespace" concept distinct from the class/module system:

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

            before.rb, working:

            def helper_fn
              puts "Hello from helper"
            end

            class Foo
              def self.bar
                helper_fn
              end
            end

            Foo.bar

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

            after.rb, not working:

            module Namespace

            def helper_fn
              puts "Hello from helper"
            end

            class Foo
              def self.bar
                helper_fn
              end
            end

            end # module Namespace

            Namespace::Foo.bar

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

            martin

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

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

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

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

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

--
Joe Gain
Jacob-Burckhardt-Str. 16
78464 Konstanz
Deutschland

t: +49 (0)7531 60389
m: +49 (0)160 4070680

Right, that's a good point. Ruby doesn't really have free functions, and
pretending it does doesn't play well with this sort of thing. I've gotten
used to having "namespace global" functions in C++, but the idiom doesn't
carry over well.

martin

···

On Wed, Jan 6, 2016 at 3:18 AM, Joe Gain <joe.gain@gmail.com> wrote:

This is also a software engineering problem, isn't it?

The code should show what the relationship is between the modules,
classes, (functions), etc.

Presumably, you have a helper function because it's a miscellaneous piece
of code required by different (other) modules and classes. Why would you
want to include the helper function in a module together with the class
that's using it? It's hard to tell from the admittedly small example, but
in the example, it would be more natural to include the helper function as
a class function, right? Or have a module of helper functions as a sibling
to the module including the using classes (and perhaps modules)?

In terms of organisation, I would prefer a module of helper function(s) to
be a sibling of the top level of the module(s) that need it.

        TopModule
  --------|-------
  > >
ModHelpers Mod
              ----|----
              > >
           MoreMods Class2 (uses ModHelpers.funky)

So the difference between Classes and Modules is that Classes inherit their
methods?
(Whereas modul methods can (normally) ONLY be used in the class they are
included?
[should be 'included' instead of 'required' in my mail before!]
A.

This is also a software engineering problem, isn't it?

The code should show what the relationship is between the modules,

classes, (functions), etc.

Presumably, you have a helper function because it's a miscellaneous

piece of code required by different (other) modules and classes. Why would
you want to include the helper function in a module together with the class
that's using it? It's hard to tell from the admittedly small example, but
in the example, it would be more natural to include the helper function as
a class function, right? Or have a module of helper functions as a sibling
to the module including the using classes (and perhaps modules)?

In terms of organisation, I would prefer a module of helper function(s)

to be a sibling of the top level of the module(s) that need it.

        TopModule
  --------|-------
  > >
ModHelpers Mod
              ----|----
              > >
           MoreMods Class2 (uses ModHelpers.funky)

Right, that's a good point. Ruby doesn't really have free functions, and

pretending it does doesn't play well with this sort of thing. I've gotten
used to having "namespace global" functions in C++, but the idiom doesn't
carry over well.

···

Am 06.01.2016 20:01 schrieb "Martin DeMello" <martindemello@gmail.com>:

On Wed, Jan 6, 2016 at 3:18 AM, Joe Gain <joe.gain@gmail.com> wrote:

martin

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

So the difference between Classes and Modules is that Classes inherit
their methods?

No. The difference between classes and modules are
1. you cannot instantiate a module
2. you can include multiple modules vs. inheriting from exactly one class.
3. you can extend an instance with a module, making a module's instance
methods methods of that instance

3 is actually a special case of 2 as it includes the module in the
singleton class of the instance. o.extend(m) is just a shortcut for
o.singleton_class.class_eval { include m } or
o.singleton_class.send(:include, m)

(Whereas modul methods can (normally) ONLY be used in the class they are
included?
[should be 'included' instead of 'required' in my mail before!]

No, this is wrong.

Kind regards

robert

···

On Thu, Jan 7, 2016 at 12:10 AM, A Berger <aberger7890@gmail.com> wrote:

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can -
without end}
http://blog.rubybestpractices.com/