Dynamic stuff and books

M

Mc Osten

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

Ross Bamford

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

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,
 
M

Mc Osten

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

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

Ross Bamford

//www.rubyist.net/~slagell/ruby/singletonmethods.html>

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

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

Mc Osten

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

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

Mc Osten

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

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

Ross Bamford

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
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).
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.
I never thought to modules that way. I'm quite used to Python, where
namespaces are authomatically managed using files. Good.


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

Logan Capaldo

--Apple-Mail-10--360199320
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed


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




--Apple-Mail-10--360199320--
 
M

Mc Osten

'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?
 
R

Ross Bamford

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"
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"
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.
Ok. In fact it told me I was calling a private method, but I did not
understand why. It's meant that way.


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

Mc Osten

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

Logan Capaldo

--Apple-Mail-14--269715994
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed


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


--Apple-Mail-14--269715994--
 
M

Mc Osten

Logan Capaldo said:
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)
 
L

Logan Capaldo

--Apple-Mail-15--265580981
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed


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)


--Apple-Mail-15--265580981--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top