New newbies Qs on Ruby 
Author Message
 New newbies Qs on Ruby

Hello!

As I explore Ruby, I like it more and more, but of course more and more
questions arise, as well.

1) It is not clear to me what is the right idiom to use when a module is
used only as a collection of some main (i.e. published) functions,
implemented by other internal (i.e. private) functions... i.e. the Module
is not intended to be included anywhere (module Math could be an
example of what I mean).

Suppose that module M publishes an 'm' function, which is implemented by
'm1', which in turn uses 'm2'.

Having exluded the 'module_function' approach:

module M
        def m2
                puts "In M2"
        end

        def m1
                m2
        end

        def m
                m1
        end
        module_function :m
end

since it won't work:

M.m -> mod3.rb:11:in `m': undefined local variable or method `m1' for
M:Module (NameError)

I tried:

module M
        def m2
                puts "In m2"
        end

        def m1
                m2
        end

        def M.m
                o=Object.new
                o.extend self
                o.m1
        end
end

M.m -> In m2

and:

module M
private
        def M.m2
                puts "In m2"
        end

        def M.m1
                m2
        end

public
        def M.m
                m1
        end
end

M.m -> In m2

Both work, but I feel like none is the right one... The first solution
requires creating and than extending an object, just for the purpose of
having something to which "attach" M's instance methods, and it looks
ugly. The second solution looks more "clean" and maybe I'm just not OO
enough to accept it :-) but IMHO m1 and m2 would "look better" as
instance methods.

So... is there another "right" way to get what I want?

2) In "Programming Ruby", it is said that the global availability of
functions like 'Array', 'open', 'putc', 'sleep', etc., depends on the
fact that such functions are module methods of Kernel, and that Kernel is
included by Object. In fact, 'Kernel.singleton_methods.sort' returns:

['Array', 'Float', 'Integer', ...]

However, also 'Kernel.private_instance_methods.sort' returns:

['Array', 'Float', 'Integer', ...]

and the two sets are almost identical:

irb(main):005:0> Kernel.singleton_methods-Kernel.private_instance_methods
[]
irb(main):006:0> Kernel.private_instance_methods-Kernel.singleton_methods
["remove_instance_variable"]

The functions actually used when called without an explicit receiver are
(of course) the private instance methods:

irb(main):001:0> module Kernel
irb(main):002:1> def sleep
irb(main):003:2> puts "No thanks, I'm not tired"
irb(main):004:2> end
irb(main):005:1> end
nil
irb(main):006:0> sleep
No thanks, I'm not tired
nil
irb(main):007:0> Kernel.sleep
<<press CTRL-C>>
IRB::Abort: abort then interrupt!!
        from E:/RUBY/lib/ruby/1.6/irb.rb:79:in `irb_abort'
        from E:/RUBY/lib/ruby/1.6/irb.rb:214:in `signal_handle'
        from E:/RUBY/lib/ruby/1.6/irb.rb:64:in `start'
        from E:/RUBY/lib/ruby/1.6/irb.rb:63:in `call'
        from (irb):7:in `sleep'
        from (irb):7

So my question is: why are the functions defined as both singletons and
private instance methods? To allow the coexistence of both
'Kernel.function()' and the 'function()' syntaxes? Or to allow
possible redefinitions of the instance methods in terms of the singletons
methods? Or... what else?

Thank you for your help,

Andrea



Mon, 28 Feb 2005 16:54:56 GMT  
 New newbies Qs on Ruby

Quote:

> Both work, but I feel like none is the right one... The first solution
> requires creating and than extending an object, just for the purpose of
> having something to which "attach" M's instance methods, and it looks
> ugly. The second solution looks more "clean" and maybe I'm just not OO
> enough to accept it :-) but IMHO m1 and m2 would "look better" as
> instance methods.

> So... is there another "right" way to get what I want?

your third is right. you can use def self.m1 instead from what i
understand, though i never do. and self will pick up the module at that
level. that's how it works ruby allows you to define module/class
methods by prefixing the module/class name and a period. honest
question, how would you want it to work?

-tom

Quote:

> 2) In "Programming Ruby", it is said that the global availability of
> functions like 'Array', 'open', 'putc', 'sleep', etc., depends on the
> fact that such functions are module methods of Kernel, and that Kernel is
> included by Object. In fact, 'Kernel.singleton_methods.sort' returns:

> ['Array', 'Float', 'Integer', ...]

> However, also 'Kernel.private_instance_methods.sort' returns:

> ['Array', 'Float', 'Integer', ...]

> and the two sets are almost identical:

> irb(main):005:0> Kernel.singleton_methods-Kernel.private_instance_methods
> []
> irb(main):006:0> Kernel.private_instance_methods-Kernel.singleton_methods
> ["remove_instance_variable"]

> The functions actually used when called without an explicit receiver are
> (of course) the private instance methods:

> irb(main):001:0> module Kernel
> irb(main):002:1> def sleep
> irb(main):003:2> puts "No thanks, I'm not tired"
> irb(main):004:2> end
> irb(main):005:1> end
> nil
> irb(main):006:0> sleep
> No thanks, I'm not tired
> nil
> irb(main):007:0> Kernel.sleep
> <<press CTRL-C>>
> IRB::Abort: abort then interrupt!!
>         from E:/RUBY/lib/ruby/1.6/irb.rb:79:in `irb_abort'
>         from E:/RUBY/lib/ruby/1.6/irb.rb:214:in `signal_handle'
>         from E:/RUBY/lib/ruby/1.6/irb.rb:64:in `start'
>         from E:/RUBY/lib/ruby/1.6/irb.rb:63:in `call'
>         from (irb):7:in `sleep'
>         from (irb):7

> So my question is: why are the functions defined as both singletons and
> private instance methods? To allow the coexistence of both
> 'Kernel.function()' and the 'function()' syntaxes? Or to allow
> possible redefinitions of the instance methods in terms of the singletons
> methods? Or... what else?

> Thank you for your help,

> Andrea

--
tom sawyer, aka transami



Mon, 28 Feb 2005 17:17:06 GMT  
 New newbies Qs on Ruby
Hello --

Quote:

> Hello!

> As I explore Ruby, I like it more and more, but of course more and more
> questions arise, as well.

> 1) It is not clear to me what is the right idiom to use when a module is
> used only as a collection of some main (i.e. published) functions,
> implemented by other internal (i.e. private) functions... i.e. the Module
> is not intended to be included anywhere (module Math could be an
> example of what I mean).

> Suppose that module M publishes an 'm' function, which is implemented by
> 'm1', which in turn uses 'm2'.

> Having exluded the 'module_function' approach:
> since it won't work:

> M.m -> mod3.rb:11:in `m': undefined local variable or method `m1' for
> M:Module (NameError)

> I tried:

[object.extend approach]

- Show quoted text -

Quote:

> and:

> module M
> private
>    def M.m2
>            puts "In m2"
>    end

>    def M.m1
>            m2
>    end

> public
>    def M.m
>            m1
>    end
> end

> M.m -> In m2

> Both work, but I feel like none is the right one... The first solution
> requires creating and than extending an object, just for the purpose of
> having something to which "attach" M's instance methods, and it looks
> ugly. The second solution looks more "clean" and maybe I'm just not OO
> enough to accept it :-) but IMHO m1 and m2 would "look better" as
> instance methods.

> So... is there another "right" way to get what I want?

Actually m1 and m2 *are* instance methods; the instance of which they
are methods just happens to be an instance of class Module :-) If you
want to avoid the explicity M. syntax, you can temporarily enter into
the virtual class of M, where (as in all class definitions) the
methods you create are instance methods of instances of the class (M
being the only instance of this particular class).

  module M
    class << self
      private
      def m2
        puts "In m2"
      end

      def m1
        m2
      end

      public
      def m
        m1
      end
    end
  end

David

--
David Alan Black                      | Register for RubyConf 2002!


Web:  http://pirate.shu.edu/~blackdav | http://www.rubyconf.com



Mon, 28 Feb 2005 18:16:15 GMT  
 New newbies Qs on Ruby
At Thu, 12 Sep 2002 17:59:50 +0900,

Quote:

> Suppose that module M publishes an 'm' function, which is implemented by
> 'm1', which in turn uses 'm2'.

> Having exluded the 'module_function' approach:

> module M
>    def m2
>            puts "In M2"
>    end

>    def m1
>            m2
>    end

>    def m
>            m1
>    end
>    module_function :m
> end

> since it won't work:

> M.m -> mod3.rb:11:in `m': undefined local variable or method `m1' for
> M:Module (NameError)

another solution:

  class Module
    def module_function_subroutine(*names)
      for m in names
         module_function m
         private_class_method m
      end
    end
  end

  module M
    def m2() puts "m2" end
    def m1() m2 end
    def m() m1 end

    module_function :m
    module_function_subroutine :m1, :m2
  end

  M.m
  M.m1 #=> NameError or NoMethodError
  M.m2 #=> NameError or NoMethodError

-- Gotoken



Mon, 28 Feb 2005 18:38:35 GMT  
 New newbies Qs on Ruby

says...

Quote:

> > So... is there another "right" way to get what I want?
> your third is right. you can use def self.m1 instead from what i
> understand, though i never do. and self will pick up the module at that
> level. that's how it works ruby allows you to define module/class
> methods by prefixing the module/class name and a period. honest
> question, how would you want it to work?

Well, any way will do, as long as I have a clear grasp of what's going on
and of the rationale behind some design choices :-) I'm exploring Ruby
and in this phase I'm really open-minded, as long as I have an
understanding of the language's workings and idioms.

It is a fact, however, that my past experiences with Perl, python and
Visual Basic, have had some (bad?) influence on my personal definition of
what a Module is.

Influenced by such languages which tend to give to 'module' the meaning
of "container of functions", I was tempted to write:

module M
private
        def m2
                puts "In m2"
        end
        def m1
                m2
        end
public
        def m
                m1
        end
end
M.m

i.e., I was tempted to avoid the 'M.*' syntax, except when absolutely
needed (to specify the namespace in which m() is defined, in this case).
But... this is just too Perlish or Pythonesque, I'm afraid... I must
upgrade my mind to an OO view :-)

(warning: what follow is my personal opinion, no flame intended :-) )

I really like Ruby. Last summer I downloaded Squeak and so I
(re)discovered the beauty of Smalltalk, which I had not used for more
than 10 years (while I was graduating). I was using Python for sysadm and
text processing tasks, and comparing it with Smalltalk convinced me that
it (Python) was too much of a kludge for my personal taste. Not to talk
about the new features introduced by Python 2.2, definitely too
bizantine for me. Someone on comp.lang.pyhton mentioned Ruby, I
downloaded it and... it was what I wanted, kind-of Smalltalk without the
Smalltalk environment, usable both for scripting and quick and dirty one-
liners and for larger projects.

Probably because I'm graduated in Computer Science, I tend to consider
every language as a work of art, and before using it for something
"useful" I spend some/a lot of time to understand it and its design
choices. Under this particular point of view, I find Ruby to be quite
"beautiful", and I'll drop Python for it.

There are some things I don't like, but compared with what I don't like
in other languages they are not so important. To be honest, I'm not sure
that the freedom in syntax allowed by Ruby promotes readability. If a
line of code is:

funcname a

how do you now if you must read it as:

funcname(a) (where a is a variable)

or

funcname(self.a())

Also I don't like things that can be written in different manners,
because I think these ambiguities make code less readable. For example a
block may be delimited by 'do...end' or by '{...}': I personally prefer
'{...}', but when I read code written by others I must remember to also
look for 'do...end'...

And I still don't understand why (see my previous posts):

- aModule.constants behaves differently from aClass.constants (but there
is a very pragmatic answer here: aClass.constants-
aClass.superclass.constants will work, while aModule.constants-
aModule.superclass.constants won't)

- module Kernel defines as singleton methods (almost) all of his private
instance methods

But this are minor things, and all in all I like what I've seen so far :-
)

Thank you for your answer, and excuse me for a lengthy reply :-)

Andrea



Tue, 01 Mar 2005 05:23:19 GMT  
 New newbies Qs on Ruby

Quote:
> another solution:

>   class Module
>     def module_function_subroutine(*names)
>       for m in names
>          module_function m
>          private_class_method m
>       end
>     end
>   end

>   module M
>     def m2() puts "m2" end
>     def m1() m2 end
>     def m() m1 end

>     module_function :m
>     module_function_subroutine :m1, :m2
>   end

>   M.m
>   M.m1 #=> NameError or NoMethodError

Yes, it works, but your answer and answers from other members (thanks to
all!) definitely convinced me of one thing: I must think in Ruby, I am
not in PlainProcedureLand anymore :-)

Andrea



Tue, 01 Mar 2005 05:24:51 GMT  
 New newbies Qs on Ruby

Quote:
> i.e., I was tempted to avoid the 'M.*' syntax, except when absolutely
> needed (to specify the namespace in which m() is defined, in this case).
> But... this is just too Perlish or Pythonesque, I'm afraid... I must
> upgrade my mind to an OO view :-)

Let me say that I deliberately avoided reading again the details
of Ruby's instance / singleton methods, include / extend, . / ::,
where names are looked up, how self is set, and the class / module
hierarchy near Object, Kernel, Module etc.

I know the basics and could learn more if I needed to use Ruby more
in practice. But I wanted to see if they are intuitive enough to
understand them from discussions here, not by reading formal rules
but by observing how they are used.

The result is that I didn't get them. Either my mind is too influenced
by other languages (mainly functional, I'm not an OO fan) or OO is
a bit unintuitive. Why each language has very different rules for
that metaclass stuff?

--
  __("<      Marcin Kowalczyk

   ^^    http://qrnik.knm.org.pl/~qrczak/



Wed, 09 Mar 2005 21:26:26 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Newbie Qs: startup time, Module.constants, chdir, Ruby distro's library

2. Qs on Ruby and DbC/Smalltalk

3. newbies and recent ex-newbies (II)

4. new page for Newbies

5. new page for Newbies

6. Newbies question on building a new tk app

7. pthread trouble with ruby-opengl on FreeBSD (was: Re: [announcement] Ruby 3D Ruby)

8. Ruby books (Ruby NG FAQ, Ruby FAQ, home page)

9. several Qs

10. Qs on CLUBMGR, Template BUG ???

11. Qs

12. Qs about language nomenclature

 

 
Powered by phpBB® Forum Software