Dynamic stuff and books

I started using ruby a couple of weeks ago and it's time to make a couple
of questions :slight_smile:
This is a long post, so I'm gonna write a short summary

1. Books
聽聽* Book on Rails
聽聽* Book on Ruby
2. Some internals (method resolution and such)
3. Module syntax

1. BOOKS
Up to now I read the first part of the online version of "Pragmatic
Programmer's Guide". I found it well done, even if I'm not really able to
find some informations I like to know. Expecially about what happens under
the hood (without having to look at the sources :slight_smile: )

I need a book about Rails, but that seem a minor problem. I see that there
are two main options (and I hope it's not OT to ask here):
a) Ruby on Rails: Up and Running
b) Agile web developement with Rails
The second one got amazing reviews on Amazon and is also linked in the
Rails page. I think I'll go with this one

I also need a book on Ruby. I think I really don't need a "pratical" book.
I'm not a new programmer and I have got some experience with dynamic
languages (exspecially with Python). So being "beginner friendly" is not a
concern.

I like quite a lot ruby and I'd like to learn how it works (and how to use
language constructs to hack it and fully use dynamic capabilities). For
example in the Python world the Nutshell is quite exaustive about how
Python "works" (without entering in the C implementation realm).
For example it explains in detail method resolution, which functions are
called under the hood (for example the __setattr__ and such).
I need that kind of book.

Another thing that could be useful is a library reference (but I already
saw there is plenty of information online). I'd go with the Ruby in a
Nutshell... but for example with Perl the Nutshell was not what I was
looking for and I had to buy Wall's book to understand some useful stuff
(ok, Perl is a *really* complex language, with lots of rules etc...)
Another Nutshell I bought was the Cocoa Nutshell (that is quite useless to
me, since duplicates a lot of informations I can get from Apple site).

Unfortunately I live in Italy and I've no bookshop nearby that deals with
english tech books. So I've no opportunity to have a look at them before
buying.

So... is there a lot more in the printed edition of Pragmatic
programmer...? How's the coverage of advanced topics?

And "The Ruby Way"? How is it?

2. I wanted to know what happens if I do

class A
def foo
end
end

a = A.new
a.foo

I found that it is *not* the same than

a.send(:foo)

I mean, if I redefine send, send is not called in "a.foo".
I thought I could redefine __send__, but ruby has not the same opinion on
the matter. :slight_smile:
For example in Python I can do this redefinining __getattribute__ (I know
it's not good to go on a language ng talking about another language). In
fact this is even more radical...

Is there a function that is called when I call a.foo? Or it's just a lookup
in a.methods? Can I trap this? The __send__ message how is handled?

And are "attr" and "attr_writer" functions? What kind of functions are
them? Is there a place on the net where are explained in detail these
subjects? A book? [ ref 1. ]

3. Module syntax
What is the difference between :: and .? I suppose they do the very same
thing. Am I correct?

Thanks in advace.

路路路

--
USB Priests for only 10$

I started using ruby a couple of weeks ago and it's time to make a couple
of questions :slight_smile:
This is a long post, so I'm gonna write a short summary

I'll skip to the bits I might be able to help with :slight_smile:

2. I wanted to know what happens if I do

class A
def foo
end
end

a = A.new
a.foo

I found that it is *not* the same than

a.send(:foo)

I mean, if I redefine send, send is not called in "a.foo".
I thought I could redefine __send__, but ruby has not the same opinion on
the matter. :slight_smile:
For example in Python I can do this redefinining __getattribute__ (I know
it's not good to go on a language ng talking about another language). In
fact this is even more radical...

Is there a function that is called when I call a.foo? Or it's just a lookup
in a.methods? Can I trap this? The __send__ message how is handled?

I've been puzzled by this before, but I think a.foo calls are dispatched
directly by Ruby, although send and __send__ will be used explicitly in
other code, including the standard libraries. Even if this were not the
case I guess you'd be unlikely to see _all_ calls go through __send__
(I'm thinking of methods implemented in C).

You can do stuff like this, though, if you want to trap calls to a given
method, whether it's implemented in Ruby or C:

  class A
    def foo
      "foo"
    end
  end

  # ... later ...

  class A
    alias :__old_foo :foo
    def foo
      # do something
      __old_foo
    end
  end

Maybe what you need, or maybe not...

And are "attr" and "attr_writer" functions? What kind of functions are
them? Is there a place on the net where are explained in detail these
subjects? A book? [ ref 1. ]

attr and friends are singleton methods (a bit like class methods) on
class Module, and are used in the scope of class or module definitions.
They're an example of metaprogramming - when called, they create new
instance methods on the class being defined, almost as if you'd 'def'ed
them yourself (although they're faster since they, like attr(.*) itself,
is implemented in C).

You might find some enlightenment on the technique in a recent Ruby
Quiz:

  Ruby Quiz - metakoans.rb (#67)

3. Module syntax
What is the difference between :: and .? I suppose they do the very same
thing. Am I correct?

Ruby tries to be flexible, but where there's ambiguity this isn't always
possible:

  module MadMod
    ACONST = 5
    class << self
      def Amethod
        "A"
      end

      def Bmethod(a)
        a.to_s
      end

      def cmethod
        "C"
      end
    end
  end

  MadMod.ACONST
  NoMethodError: undefined method `ACONST' for MadMod2:Module
          from (irb):84

路路路

On Tue, 2006-02-28 at 01:38 +0900, Mc Osten wrote:
          from :0

  MadMod::ACONST
  # => 5

  MadMod.Amethod
  # => "A"

  MadMod::Amethod
    NameError: uninitialized constant MadMod2::Amethod
          from (irb):82
          from :0

  MadMod.Bmethod(10)
  # => "10"

  MadMod::Bmethod(10)
  # => "10"

  MadMod.cmethod
  # => "C"

  MadMod::cmethod
  # => "C"

Notice the last four (B and cmethod), where there is no ambiguity
(Bmethod takes arguments, and so cannot be a constant, while cmethod
lacks the initial lowercase letter that identifies constants). Ruby
allows either :: or . to be used here, but generally you should probably
stick to using :: for constant references, and . for method calls since
it avoids any confusion for the parser and (more importantly) reader.

Hope that helps,
--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

I'll skip to the bits I might be able to help with :slight_smile:

It's the reason why i put the index. I supposed many people would have
answered the more "amusing" ruby questions, but not the book ones :slight_smile:
I perfectly know how boring are those "noob questions", unfortunately it's
almost irresistible to ask them. :))

I've been puzzled by this before, but I think a.foo calls are dispatched
directly by Ruby, although send and __send__ will be used explicitly in
other code, including the standard libraries. Even if this were not the
case I guess you'd be unlikely to see _all_ calls go through __send__
(I'm thinking of methods implemented in C).

Ok. So I assume that wasn't the correct way to do it and stop trying to
fool ruby with __send__.

You can do stuff like this, though, if you want to trap calls to a given
method, whether it's implemented in Ruby or C:

  class A
    def foo
      "foo"
    end
  end

  # ... later ...

  class A
    alias :__old_foo :foo
    def foo
      # do something
      __old_foo
    end
  end

Maybe what you need, or maybe not...

I suppose it does it. I totally missed that function. It gives me a lot of
flexibility, I think I can use it to solve my troubles.

attr and friends are singleton methods (a bit like class methods) on
class Module, and are used in the scope of class or module definitions.

Are they the rb_attr functions defined in eval.c? I think so. Good.
And I did not know they were called "singleton methods". I probably should
read the Practical Programmer Guide with more attention (in fact I was to
amazed to reason properly).

I found some more information here:
<http://www.rubyist.net/~slagell/ruby/singletonmethods.html&gt;

Well, another source of information... here the thing gets more
interesting. Well an example of a singleton method from the site above is

class SingletonTest
  def size
    25
  end
end

test2 = SingletonTest.new

def test2.size
   10
end

[ and I'm not really sure I do like this... anyway ]

Then I read here (where "here" is
<http://www.rubycentral.com/faq/rubyfaq-8.html&gt;\) that if I declare a
singleton method for a class object I get a "class method". That is to say

class Foo
  def Foo.bar
    "foobar"
  end
end

And so I think I found a really important use for singleton methods, so I
think I should love them, since I love class methods. :slight_smile:

And now...

Methods which are defined in class Class can be used as class methods for every class(!)

That is to say I could imagine that if Ruby were written in Ruby I would
have

class Class
  def Class.attr(symbol, v)
    # ...
  end
end

Right? [ no, I'm backtracking and I know I'm wrong, but I don't know why ]

And now "the donkey falls" (rough translation of an italian motto -- of
course the donkey mentioned above it is me).

Class is Object class. Right? ( I think so, and irb tends to confirm my
supposition -- and I should subscribe this ng on my Mac since I'm starting
to hate fxri *give* *me* *readline* ).

The first question that springs into my mind is:
- May I define a class whose type is not Class? That is to say a class Foo
such that Foo.class is the object Bang? -- in other terms has Ruby "custom
metaclasses"?

- The second is: is there some Ruby object that is not an Object (and
fortunately I'm case sensitive enought not mess with the principle of
non-contraddiction)? As far as I can see, even Classes are Objects [ and
that's quite consistent with Python too, since types are objects ]

But... how can it be that *every* Class object... no, I know.
So if I do some

class Class
  def Class.foo(sym)
    puts "You fooed #{sym}"
  end
end

what am I really doing? This does not work how I expected, that is

class Foo
  foo :hi
  def bar
    "bar"
  end
end

explodes... so eventually the donkey fell[0]. What's wrong?

路路路

On Tue, 28 Feb 2006 02:18:59 +0900, Ross Bamford wrote:

----
[0] If someone is interested "Casca l'asino" [ the forementioned "The
donkey falls" ] is roughly equivalent to "All the knots get back to the
comb", but I quite feel more like a donkey than like a knot. It's probably
because I.am_a? Mammal, anyway )

They're an example of metaprogramming - when called, they create new
instance methods on the class being defined, almost as if you'd 'def'ed
them yourself (although they're faster since they, like attr(.*) itself,
is implemented in C).

Yes. I do like this. In fact it is what I was looking for. Unfortunately as
you may have noticed I tend to write before I think, thus producing posts
that are comparable with book chapters. Not because they're good, but
because they are long. Should learn to write haiku posts, definitely.

You might find some enlightenment on the technique in a recent Ruby
Quiz:

  Ruby Quiz - metakoans.rb (#67)

This is *wonderful*. And I feel noob. There are a lot of things I do not
understand. So... for example

Class::new is a bit strange to me. I suppose I learned a new thing. For
example this works as expected

C = Class::new do
  def foo
    "foo"
  end
end

puts C.class

c = C.new
puts c.foo
puts c.class

So if I pass Class::new a block, the block is executed as if it were the
"body" of a class statement. Right? May I generalize this? There are other
useful Class::methods to learn?

Class::new looks like the object oriented version of lambda. Is it true?

But then...

class << self

def

is mysterious to me.

And somewhere I also saw some &word. What's that? Sorry for the newbie
question.

Notice the last four (B and cmethod), where there is no ambiguity
(Bmethod takes arguments, and so cannot be a constant, while cmethod
lacks the initial lowercase letter that identifies constants). Ruby
allows either :: or . to be used here, but generally you should probably
stick to using :: for constant references, and . for method calls since
it avoids any confusion for the parser and (more importantly) reader.

Ok. Got it. But for simple functions in a module, shouldn't I use ::?
I tend not to think to functions like "methods" of an instance of a module
object (I should definitely have a break), but rather ... well, :: is more
appropriate in this case, isn't it? :slight_smile:

--
USB Priests for only 10$

<http://www.rubyist.net/~slagell/ruby/singletonmethods.html&gt;

Well, another source of information... here the thing gets more
interesting. Well an example of a singleton method from the site above is

class SingletonTest
  def size
    25
  end
end

test2 = SingletonTest.new

def test2.size
   10
end

Answering a later question you had, the above singleton method could be
defined like:

  class << test2
    def size
      10
    end
  end

This is a singleton class definition, which as you noticed is often used
in regular class/module definition contexts to define 'class methods'.
Since self refers to the class being defined, the following:

  class SomeClass
    # 'self' is SomeClass
    class << self
      def size
        10
      end
    end
  end

creates a singleton method on the SomeClass class instance, which is
referred to by the constant 'SomeClass', hence the ability to call it by
'SomeClass.size'.

The first question that springs into my mind is:
- May I define a class whose type is not Class? That is to say a class Foo
such that Foo.class is the object Bang? -- in other terms has Ruby "custom
metaclasses"?

Well, you can't subclass Class. You can do a bit of this kind of thing
with Module (a superclass of Class), but bear in mind that class names
are just like any other constant in Ruby, so you could do

  class OtherClass
    def new
      "Aha!"
    end
  end

  Foo = OtherClass.new

  Foo.class
  # => OtherClass

  Foo.new
  # => "Aha!"

which is all very confusing, so probably best not to (outside of a few
cases you'll find later I guess).
  

- The second is: is there some Ruby object that is not an Object (and
fortunately I'm case sensitive enought not mess with the principle of
non-contraddiction)? As far as I can see, even Classes are Objects [ and
that's quite consistent with Python too, since types are objects ]

Yes, everything in Ruby is an object, at least from the point of view of
your Ruby code.

But... how can it be that *every* Class object... no, I know.
So if I do some

class Class
  def Class.foo(sym)
    puts "You fooed #{sym}"
  end
end

what am I really doing? This does not work how I expected, that is

class Foo
  foo :hi
  def bar
    "bar"
  end
end

explodes... so eventually the donkey fell[0]. What's wrong?

Remember that class definitions execute in the context of the class
being defined - an _instance_ of Class (referred to by 'self' there). So
for the code to work, you'd just need to define an instance method on
Class, rather than a singleton method.

For most purposes you'll want to define on Module instead, which allows
your method in both class and module definition contexts.

----
[0] If someone is interested "Casca l'asino" [ the forementioned "The
donkey falls" ] is roughly equivalent to "All the knots get back to
the
comb", but I quite feel more like a donkey than like a knot. It's
probably
because I.am_a? Mammal, anyway )

In Ruby Mammal would have to be a module, and I'd say
self.kind_of?(Mammal) :slight_smile:

And somewhere I also saw some &word. What's that? Sorry for the newbie
question.

As you saw, a lot of stuff in Ruby is done with blocks. You can attach
blocks to method calls, and one of the ways this is done is by declaring
the final argument with a leading ampersand.

Theres a bit about it here:

  http://www.rubycentral.com/book/tut_containers.html

(esp. 'Blocks can be closures' near the bottom)

> Notice the last four (B and cmethod), where there is no ambiguity
> (Bmethod takes arguments, and so cannot be a constant, while cmethod
> lacks the initial lowercase letter that identifies constants). Ruby
> allows either :: or . to be used here, but generally you should probably
> stick to using :: for constant references, and . for method calls since
> it avoids any confusion for the parser and (more importantly) reader.

Ok. Got it. But for simple functions in a module, shouldn't I use ::?
I tend not to think to functions like "methods" of an instance of a module
object (I should definitely have a break), but rather ... well, :: is more
appropriate in this case, isn't it? :slight_smile:

Well, in Ruby functions are methods :). I suppose in the unambiguous
cases it's really up to you, but as I say I'd recommend sticking with
the 'standard' (?) usage, simply because it avoids strange errors and
odd behaviour in cases where it's not 100% clear cut what you're
referring to (or worse, could become so after refactoring).

路路路

On Tue, 2006-02-28 at 06:33 +0900, Mc Osten wrote:

On Tue, 28 Feb 2006 02:18:59 +0900, Ross Bamford wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Answering a later question you had, the above singleton method could be
defined like:

  class << test2
    def size
      10
    end
  end

Quite interesting. I understand its semantic, but not its syntax. That is
to say "class" is a keyword. So this is a "new syntax"?

I think that since I can << array the syntax is not *that* new. Still quite
impressive... well as I said

Every time I do

class << something
code
end

I'm evaluating "code" in the "something" context? No.. this is not correct.
I understand the example, but I'm not able to make abstraction.

I also suppose i can

module << something
code
end

I suppose that I should see this as: "add the things I define below to the
object something...
I think I'm not really prepared on the fundamentals. Is there a place where
I can learn (for example what really does the interpreter when it
encounters a "class" definition and such)

So I suppose than

class Something
# code
end

is "synactic sugar" for

Somtheing = Class::new do
  # code
end

And if I define something in there, it's like defining a function and then
put it in public_instance_methods (a part that explicitly put it there does
not word, but it works if I public :foo)

This is a singleton class definition, which as you noticed is often used
in regular class/module definition contexts to define 'class methods'.
Since self refers to the class being defined, the following:

  class SomeClass
    # 'self' is SomeClass
    class << self
      def size
        10
      end
    end
  end

creates a singleton method on the SomeClass class instance, which is
referred to by the constant 'SomeClass', hence the ability to call it by
'SomeClass.size'.

Ok. This is clear. So...

When class'ing I'm defining a new Class instance. Then I append methods to
it. I think I got it.

Well, you can't subclass Class. You can do a bit of this kind of thing
with Module (a superclass of Class), but bear in mind that class names
are just like any other constant in Ruby, so you could do

  class OtherClass
    def new
      "Aha!"
    end
  end

  Foo = OtherClass.new

  Foo.class
  # => OtherClass

  Foo.new
  # => "Aha!"

which is all very confusing, so probably best not to (outside of a few
cases you'll find later I guess).

Well it looks like a factory object, since then if I Foo.new.class I get
(correctly) String.

Yes, everything in Ruby is an object, at least from the point of view of
your Ruby code.

I knew it was an object. I suppose I can say it is an Object.

Remember that class definitions execute in the context of the class
being defined - an _instance_ of Class (referred to by 'self' there). So
for the code to work, you'd just need to define an instance method on
Class, rather than a singleton method.

Well... good. Understood. In fact this works as expected

class Class
  def foo(sym)
    puts "You fooed #{sym}"
  end
end

class Foo
  foo :hi
  def bar
    "bar"
  end
end

I've seen that Rails uses a lot this kind of things (for example for
validation) But I suppose they do not add the belongs_to and similar
directly to Class (this is not a question I can go and check the code)
and rather do something like:

class Foo
  def Foo.bar(sym)
    puts "Baaaar: #{sym}"
  end
end

class SubFoo < Foo
   def bar_method
      "bar"
   end
   
   bar :bar_method
end

Then the main question: am I supposed to do this sort of things or is
someone gonna kill me? For example suppose I want to create kind of
synchronized methods (in the Java sense).
Syntactically it is quite beautiful to

synchronize :foo

[ and I think in Monitor.synchronize I would alias :foo, define a
synchronized version of foo that wraps the old :foo ]

If I can do I (theoretically) solved the problem that led me to ask the
first question. But I'm afraid it can't be *that* simple... [ I know Mutex
and works well, it is just to exploit the language features to add new
semantic if needed ].

For most purposes you'll want to define on Module instead, which allows
your method in both class and module definition contexts.

I never thought to modules that way. I'm quite used to Python, where
namespaces are authomatically managed using files. Good.

In Ruby Mammal would have to be a module, and I'd say
self.kind_of?(Mammal) :slight_smile:

Why it would be a Module? In fact I could have functions and methods that
manipulate mammals and I may want to have the forementioned Donkey class to
subclass it.
It's probably a question of Ruby style I've not yet encountered.

As you saw, a lot of stuff in Ruby is done with blocks. You can attach
blocks to method calls, and one of the ways this is done is by declaring
the final argument with a leading ampersand.

Yes. And I do like them a lot. It's one of those things you say "how have I
done _before_?".

But it does work even without...

def blrun(a)
   puts a
   yield
end

def blrun2(a, &b)
   puts a
   yield b
end

blrun("a") { puts "b" }
blrun2("a") { puts "b" }

I suppose it is useful if you want to "give a name" to the block. Am I
correct?

Theres a bit about it here:

  http://www.rubycentral.com/book/tut_containers.html

(esp. 'Blocks can be closures' near the bottom)

I go and study.
EDIT: I read that. Amazingly enought I forgot the use of & at all. I
suppose I should go through that book again.

Well, in Ruby functions are methods :).

Whose methods are them? I suppose it should be Object or maybe Kernel
(which in fact should be the same since Object includes Kernel, right?)

But I tried to define a method and call it with Object.method and gives
error...

路路路

On Tue, 28 Feb 2006 07:57:19 +0900, Ross Bamford wrote:

--
USB Priests for only 10$

> Answering a later question you had, the above singleton method could be
> defined like:
>
> class << test2
> def size
> 10
> end
> end

Quite interesting. I understand its semantic, but not its syntax. That is
to say "class" is a keyword. So this is a "new syntax"?

'class' here is doing what you expect it to do - defining a class. But
the class that's being defined is a singleton class belonging to the
object on the rhs of the <<. Basically, objects in ruby can have two
classes - the class of which they are an instance, and a singleton class
that relates to (and supplies methods for) just that object. This syntax
is for use with the latter.

I think that since I can << array the syntax is not *that* new. Still quite
impressive... well as I said

Every time I do

class << something
code
end

I'm evaluating "code" in the "something" context? No.. this is not correct.
I understand the example, but I'm not able to make abstraction.

Not quite. You're actually evaluating it in the context of an instance
of Class, that being the singleton class for 'something'.

Try this:

  class << something
    p self
  end

Since almost everything in Ruby is an expression, you can also do this:

  class SomeClass
    def singclass
      class << self
        self
      end
    end
  end

  s = SomeClass.new
  # => #<SomeClass:0xb7e85d9c>

  s.singclass
  # => #<Class:#<SomeClass:0xb7e85d9c>>
  
Notice how the Class returned relates to just that SomeClass instance.
(this for the sake of example, if you were to need it you'd probably
define it elsewhere).

I also suppose i can

module << something
code
end

No, singleton modules aren't (AFAIK) supported.

So I suppose than

class Something
# code
end

is "synactic sugar" for

Somtheing = Class::new do
  # code
end

Mostly that's true, but there is at least one difference to keep in mind
- multiple class SomeClass ... definitions will 'reopen' the existing
class and allow new methods to be added:

  class TooClz
    def a; "a"; end
  end
  # => nil

  TooClz.new.a
  # => "a"

  class TooClz
    def b; "b"; end
  end
  # => nil

  TooClz.new.a
  # => "a"
  TooClz.new.b
  # => "b"

While the assignment here scuppers that (notice Ruby complaining about
the constant being already initialized):

  Clz = Class.new { def a; "a"; end }
  # => Clz

  Clz.new.a
  # => "a"

  Clz = Class.new { def b; "b"; end }
  (irb):24: warning: already initialized constant Clz
  # => Clz

  Clz.new.a
  NoMethodError: undefined method `a' for #<Clz:0xb7e7ad34>
          from (irb):26

> Well, you can't subclass Class. You can do a bit of this kind of thing
> with Module (a superclass of Class), but bear in mind that class names
> are just like any other constant in Ruby, so you could do
>
> class OtherClass
> def new
> "Aha!"
> end
> end
>
> Foo = OtherClass.new
>
> Foo.class
> # => OtherClass
>
> Foo.new
> # => "Aha!"
>
> which is all very confusing, so probably best not to (outside of a few
> cases you'll find later I guess).

Well it looks like a factory object, since then if I Foo.new.class I get
(correctly) String.

Exactly, which is kind of how I see classes in Ruby, too (especially
since instances can change after instantiation thanks to the singleton
class).

> Yes, everything in Ruby is an object, at least from the point of view of
> your Ruby code.

I knew it was an object. I suppose I can say it is an Object.

Yes, sorry, I meant both object and Object there :slight_smile:

Then the main question: am I supposed to do this sort of things or is
someone gonna kill me? For example suppose I want to create kind of
synchronized methods (in the Java sense).
Syntactically it is quite beautiful to

synchronize :foo

[ and I think in Monitor.synchronize I would alias :foo, define a
synchronized version of foo that wraps the old :foo ]

Yes, you could do something like that:

  class Module
    def synchronize(sym)
      alias_method("__orig_#{sym}", sym)
      define_method(sym) do |*args|
        puts "Sync"
        send("__orig_#{sym}", *args)
        puts "Done"
      end
    end
  end

  class SomeClass
    def syncme(a)
      puts a
    end

    synchronize :syncme
  end

  SomeClass.new.syncme("hello")
  # output:
  # Sync
  # hello
  # done

And no, no-one is going to get upset about it (well, no-one who does
Ruby anyway). I consider this kind of metaprogrammability to be one of
Ruby's sleekest features. Whether your boss, or your customer, or
whoever else, gets upset about it depends on too many external factors
to predict :slight_smile:

As you mentioned, there are other tools to help with synchronization
(e.g. Mutex) - this is just an example of what you _could_ do.

> For most purposes you'll want to define on Module instead, which allows
> your method in both class and module definition contexts.

I never thought to modules that way. I'm quite used to Python, where
namespaces are authomatically managed using files. Good.

> In Ruby Mammal would have to be a module, and I'd say
> self.kind_of?(Mammal) :slight_smile:

Why it would be a Module? In fact I could have functions and methods that
manipulate mammals and I may want to have the forementioned Donkey class to
subclass it.
It's probably a question of Ruby style I've not yet encountered.

The more I thought about this, the more I imagined an enormous class
hierarchy representing the natural world, so I decided to stop thinking
about it in the end :slight_smile:

> As you saw, a lot of stuff in Ruby is done with blocks. You can attach
> blocks to method calls, and one of the ways this is done is by declaring
> the final argument with a leading ampersand.

Yes. And I do like them a lot. It's one of those things you say "how have I
done _before_?".

But it does work even without...

def blrun(a)
   puts a
   yield
end

def blrun2(a, &b)
   puts a
   yield b
end

blrun("a") { puts "b" }
blrun2("a") { puts "b" }

I suppose it is useful if you want to "give a name" to the block. Am I
correct?

'yield' is usually the way I'd recommend you go, but yes, sometimes you
need to do something with the block other than call it right away.

The & can also be used with block methods to allow an existing Proc to
be used as the method's block, e.g.

  blk = lambda { puts "b" }
  blrun("a", &blk)

This comes in handy too when you want to pass a block attached to one
method to another method.

(Aside, the 'yield b' in your second example above will actually pass
the block as an argument to itself).

> Well, in Ruby functions are methods :).

Whose methods are them? I suppose it should be Object or maybe Kernel
(which in fact should be the same since Object includes Kernel, right?)

But I tried to define a method and call it with Object.method and gives
error...

Top-level 'functions' are private methods on Object (I was sure it was
Kernel but it doesn't appear so):

  def amethod
    "Hey!"
  end

  p Object.private_instance_methods.include?('amethod')
  # => true

  Object.new.send(:amethod)
  # => "Hey!"

Since they're private, and on Object, you get the expected behaviour
that you can only call them with no receiver, and from anywhere.

路路路

On Tue, 2006-02-28 at 20:18 +0900, Mc Osten wrote:

On Tue, 28 Feb 2006 07:57:19 +0900, Ross Bamford wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Well actually it still has only one class. What happens is it injects the Singleton class into the inheritance hierarchy of the object before it's original class.

sort of like this (In not valid ruby):

a = "hello"

class SingletonClassForA < String
     def a_method
            self << " world"
     end
end

a.change_class(SingletonClassForA)

a.a_method

puts a

"hello world"

路路路

On Feb 28, 2006, at 8:03 AM, Ross Bamford wrote:

'class' here is doing what you expect it to do - defining a class. But
the class that's being defined is a singleton class belonging to the
object on the rhs of the <<. Basically, objects in ruby can have two
classes - the class of which they are an instance, and a singleton class
that relates to (and supplies methods for) just that object. This syntax
is for use with the latter.

'class' here is doing what you expect it to do - defining a class. But
the class that's being defined is a singleton class belonging to the
object on the rhs of the <<. Basically, objects in ruby can have two
classes - the class of which they are an instance, and a singleton class
that relates to (and supplies methods for) just that object. This syntax
is for use with the latter.

Ok. Quite got it. It's kind of a new viewpoint to me. In fact it can be
done even in Python, but then it is more natural to see it as "I changed a
method in the dictionary methods" [ basically python objects act much like
dictionaries -- hashes in the ruby world ]

It's probably something I have to meditate upon. Injecting classes I mean.

Not quite. You're actually evaluating it in the context of an instance
of Class, that being the singleton class for 'something'.

So not in the something context, but in a "subclass without name" (the
singleton class). Ok.

So everytime I'm doing something with << and classes I'm working with
subclasses?
  

Notice how the Class returned relates to just that SomeClass instance.
(this for the sake of example, if you were to need it you'd probably
define it elsewhere).

I love it. Quite more clear than the "update dictionary" version.

No, singleton modules aren't (AFAIK) supported.

irb agrees.

Mostly that's true, but there is at least one difference to keep in mind
- multiple class SomeClass ... definitions will 'reopen' the existing
class and allow new methods to be added:

Yes. That's true. I didn't think about it. It's one of the things I really
love, indeed. But...

Is there anyway to "reopen" a class with the "raw" syntax?

         Something.reopen do
           # code...
         end

I had a look at the ri documentation (and I found out there is a lot of
interesting stuff...) and found anything.
It appears that appending stuff to the "methods" and "public_methods"
arrays is not the way to go...

And no, no-one is going to get upset about it (well, no-one who does
Ruby anyway). I consider this kind of metaprogrammability to be one of
Ruby's sleekest features. Whether your boss, or your customer, or
whoever else, gets upset about it depends on too many external factors
to predict :slight_smile:

This is not an issue... it was just a matter of "style". I come from
Python, there are lots of things that are perfectly legal, but are felt
"unpythonic" and thus better avoided (I'm not speaking of metaprogramming,
but of "bad style").
I was asking if the "good Ruby programmer" was "allowed" to hack in this
sense even in production or if it was considered just an "intellectual
exercise" (as are obfuscated C/Perl contexts).

The more I thought about this, the more I imagined an enormous class
hierarchy representing the natural world, so I decided to stop thinking
about it in the end :slight_smile:

:))

'yield' is usually the way I'd recommend you go, but yes, sometimes you
need to do something with the block other than call it right away.

Ok.

(Aside, the 'yield b' in your second example above will actually pass
the block as an argument to itself).

Uh. Quite interesting... suppose I can do something really nasty with this.
I like it! :slight_smile:

Top-level 'functions' are private methods on Object (I was sure it was
Kernel but it doesn't appear so):

Ok. In fact it told me I was calling a private method, but I did not
understand why. It's meant that way.

Since they're private, and on Object, you get the expected behaviour
that you can only call them with no receiver, and from anywhere.

May I ask why?

路路路

On Tue, 28 Feb 2006 22:03:04 +0900, Ross Bamford wrote:

--
USB Priests for only 10$

> Not quite. You're actually evaluating it in the context of an instance
> of Class, that being the singleton class for 'something'.

So not in the something context, but in a "subclass without name" (the
singleton class). Ok.

So everytime I'm doing something with << and classes I'm working with
subclasses?
  
In terms of the implementation, it would seem so (thanks, Logan), and
indeed it makes sense in your code too:

  str = "one"
  # => "one"

  class << str
    def gsub(*args, &blk)
      super(*args, &blk)
    end
  end
  # => nil

  str.gsub(/o/,'O')
  # => "One"

> Mostly that's true, but there is at least one difference to keep in mind
> - multiple class SomeClass ... definitions will 'reopen' the existing
> class and allow new methods to be added:

Yes. That's true. I didn't think about it. It's one of the things I really
love, indeed. But...

Is there anyway to "reopen" a class with the "raw" syntax?

         Something.reopen do
           # code...
         end

In a way, yes:

  class Something
    def a; 'a'; end
  end
  # => nil

  Something.class_eval do
    def b; 'b'; end
  end
  # => nil

  Something.new.a
  # => "a"
  Something.new.b
  # => "b"

> And no, no-one is going to get upset about it (well, no-one who does
> Ruby anyway). I consider this kind of metaprogrammability to be one of
> Ruby's sleekest features. Whether your boss, or your customer, or
> whoever else, gets upset about it depends on too many external factors
> to predict :slight_smile:

This is not an issue... it was just a matter of "style". I come from
Python, there are lots of things that are perfectly legal, but are felt
"unpythonic" and thus better avoided (I'm not speaking of metaprogramming,
but of "bad style").
I was asking if the "good Ruby programmer" was "allowed" to hack in this
sense even in production or if it was considered just an "intellectual
exercise" (as are obfuscated C/Perl contexts).

I don't consider metaprogramming bad style, and I think it's a fairly
well-used practice over here. It is potentially very dangerous, and can
easily be misused (and overused) with really hard-to-debug results, but
just as a butcher works better with sharp knives, sometimes so do we.
Generally I'd advise metaprogramming be used only when no other
'standard' technique can do the job, or would be so inelegant as to be
pointless.

> Top-level 'functions' are private methods on Object (I was sure it was
> Kernel but it doesn't appear so):

Ok. In fact it told me I was calling a private method, but I did not
understand why. It's meant that way.

> Since they're private, and on Object, you get the expected behaviour
> that you can only call them with no receiver, and from anywhere.

May I ask why?

Because they're defined on Object, they are available everywhere (in the
context of any 'self'). And because they're private, they can only be
called with the implicit 'self', so they act like functions.

You can use 'send' to call them, of course, which demonstrates the
point:

  def one
    p self
  end

  one
  # => main

  # This line would raise a private method error
  #"hey".one

  "hey".send(:one)
  # => "hey"

  88.send(:one)
  # => 88

('main' is just an Object corresponding to the top-level scope).

路路路

On Wed, 2006-03-01 at 21:48 +0900, Mc Osten wrote:

On Tue, 28 Feb 2006 22:03:04 +0900, Ross Bamford wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Classes aren't really ever closed

class A
    def a
       puts "hello"
    end
end

class A
      def b
        puts "world"
      end
end

c = A.new
c.a
c.b

#results in
hello
world

路路路

On Mar 1, 2006, at 7:48 AM, Mc Osten wrote:

Is there anyway to "reopen" a class with the "raw" syntax?

         Something.reopen do
           # code...
         end

I don't consider metaprogramming bad style, and I think it's a fairly
well-used practice over here. It is potentially very dangerous, and can
easily be misused (and overused) with really hard-to-debug results, but
just as a butcher works better with sharp knives, sometimes so do we.
Generally I'd advise metaprogramming be used only when no other
'standard' technique can do the job, or would be so inelegant as to be
pointless.

Ok. That's pretty much the same advise I give when someone asks me the same
about Python. Good, this is not something to be included in the context
switch.

Because they're defined on Object, they are available everywhere (in the
context of any 'self'). And because they're private, they can only be
called with the implicit 'self', so they act like functions.

Ok. Quite makes sense. In the first instance I didn't realize Ruby hasn't
got "just functions". Luckily enough I can use them as regular functions (I
was thinking about the funny integralism of one famous language).

Many thanks, you helped me a lot to clarify some obscure points I had.

路路路

On Wed, 1 Mar 2006 22:29:17 +0900, Ross Bamford wrote:

--
USB Priests for only 10$

We were discussing about another syntax to reopen the class.

Since I could use both the raw syntax

    C = Class::new do

    end

and

    class C

    end

I expected there should be some "raw" command to reopen the class.

Ross pointed out I can do it with class_eval (that was what I was
looking for)

路路路

Logan Capaldo <logancapaldo@gmail.com> wrote:

Classes aren't really ever closed

--
Uccidete i filosofi e tenetevi riso e bacchette per voi.

Sorry by "raw" I assumed you meant the "normal" syntax, as opposed to the meta-programming syntax. (.class_eval)

路路路

On Mar 1, 2006, at 4:38 PM, Mc Osten wrote:

Since I could use both the raw syntax