Forum: Ruby Dynamic stuff and books

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mc Osten (Guest)
on 2006-02-27 18:42
(Received via mailing list)
I started using ruby a couple of weeks ago and it's time to make a
couple
of questions :)
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 :) )

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. :)
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.
Ross B. (Guest)
on 2006-02-27 19:19
(Received via mailing list)
On Tue, 2006-02-28 at 01:38 +0900, Mc Osten wrote:
> I started using ruby a couple of weeks ago and it's time to make a couple
> of questions :)
> 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 :)

>
>
> 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:

	http://www.rubyquiz.com/quiz67.html

> 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
	        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,
Mc Osten (Guest)
on 2006-02-27 23:34
(Received via mailing list)
On Tue, 28 Feb 2006 02:18:59 +0900, Ross B. wrote:

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

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 :)
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__.

>
> 	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/singletonmeth...

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>) 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. :)

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?

----
[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:
>
> 	http://www.rubyquiz.com/quiz67.html

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? :)
Ross B. (Guest)
on 2006-02-28 00:58
(Received via mailing list)
On Tue, 2006-02-28 at 06:33 +0900, Mc Osten wrote:
> 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.

>
> 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) :-)

> 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)

> appropriate in this case, isn't it? :)
>

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).
Mc Osten (Guest)
on 2006-02-28 13:21
(Received via mailing list)
On Tue, 28 Feb 2006 07:57:19 +0900, Ross B. wrote:

> 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)

> 	  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.

> 	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) :-)

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.

> 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...
Mc Osten (Guest)
on 2006-02-28 14:59
(Received via mailing list)
On Tue, 28 Feb 2006 07:57:19 +0900, Ross B. wrote:

> 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)

> 	  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.

> 	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) :-)

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...
Ross B. (Guest)
on 2006-02-28 15:05
(Received via mailing list)
On Tue, 2006-02-28 at 20:18 +0900, Mc Osten wrote:
>
> 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 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.

> 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

> > 	Foo = OtherClass.new
> 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 :)

> 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 :)

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

> 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 :)

>    puts a
> 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.
Logan C. (Guest)
on 2006-03-01 04:38
(Received via mailing list)
On Feb 28, 2006, at 8:03 AM, Ross B. 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.

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"
Mc Osten (Guest)
on 2006-03-01 14:48
(Received via mailing list)
On Tue, 28 Feb 2006 22:03:04 +0900, Ross B. 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.

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 :)

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 :)

:))

> '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! :)


> 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?
Ross B. (Guest)
on 2006-03-01 15:29
(Received via mailing list)
On Wed, 2006-03-01 at 21:48 +0900, Mc Osten wrote:
> On Tue, 28 Feb 2006 22:03:04 +0900, Ross B. wrote:
> > 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"

>            # 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"

> 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).
Mc Osten (Guest)
on 2006-03-01 22:38
(Received via mailing list)
On Wed, 1 Mar 2006 22:29:17 +0900, Ross B. wrote:


> 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.
Logan C. (Guest)
on 2006-03-01 22:51
(Received via mailing list)
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
>

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
unknown (Guest)
on 2006-03-01 23:38
(Received via mailing list)
Logan C. <removed_email_address@domain.invalid> wrote:

> Classes aren't really ever closed

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 C. (Guest)
on 2006-03-02 00:00
(Received via mailing list)
On Mar 1, 2006, at 4:38 PM, Mc Osten wrote:

> Since I could use both the raw syntax

Sorry by "raw" I assumed you meant the "normal" syntax, as opposed to
the meta-programming syntax. (.class_eval)
This topic is locked and can not be replied to.