On 2005-02-19, gga <GGarramuno / aol.com> wrote:
> 2) I also would like to have some modules that work either as include
> modules or as modules with stand-alone methods.  Problem is that ruby
> will not "include" class methods.
> That is, say I have a funcion called runcmd() to run a shell command
> and do stdin/out/err piping.  This function is rather common, so I
> would like to have:
>
> module Shell
>     def self.runcmd(cmd)
>        # ....do tons of stuff
>     end
>     def runcmd(cmd)
>        Shell.runcmd(cmd)
>     end
> end
>
> So I can do:
>
> Shell.runcmd("ls")
>
> or:
>
> class Backup
>      include Shell
>      def doit
>         runcmd("ls")
>         runcmd("cmd2")
>      end
> ...etc..
> end
>
>
> The above works but it seems kind of silly and wasteful for something
> that to me seems pretty common (not to mention that the instance method
> access will likely be slower, too).

I've faced this problem too, and I find out a workaround which may be
not very elegant, but results in only a contstant number of extra code
lines (not like the trivial solution shown above, which uses extra code
lines in a linear rate to the number of class methods in Shell).

module Shell
  # what would be module methods are rather collected in a separate
  # module
  module Addons
    def runcmd(cmd)
       # ....do tons of stuff
    end
  end
 
  # a custom inclusion method
  def useme aMod
    aMod.send :include, self
    aMod.extend Addons
  end
end

class Backup
  Shell.useme self
  ...
end

Backup.runcmd "ls"
#works

If you want instances of Backup to have direct access to runcmd, you can
include Addon in Shell. I don't see though the purpose of turning
class/module methods into instance methods (yeah, you save a few
characters of code by doing that, but it seems to be a bad design,
unless you are about breaking out of the class based object model).

Csaba