Thought question: Where does "new" come from?

I’ve been brooding again on the circularities
in Ruby’s classes.

Now I’m thinking of a particular question:
How would you explain where “new” comes from
in a class?

It’s easy to say that all classes are objects
of the type Class.

So for example, Object has a “new” because it’s
a Class. But on the other hand, Class is an
Object.

Would you say that Object gets “new” from Class,
or vice versa? Or neither? Or should I just not
worry about it?

This arose because I was trying to draw a picture
of Ruby’s entire object model.

Comments, anyone? Matz, Dave, Guy, David? Others?

It’s 1:35 a.m. my time. I should go to bed. I’ve
probably said something incorrect in this email.

Hal

Hi,

How would you explain where “new” comes from
in a class?

From the Class class.

This arose because I was trying to draw a picture
of Ruby’s entire object model.

Did you check the chart in object.c?

/*
 * Ruby's Class Hierarchy Chart
···

In message “Thought question: Where does “new” come from?” on 02/08/15, “Hal E. Fulton” hal9000@hypermetrics.com writes:
*
* ±-----------------+
* | |
* Object---->(Object) |
* ^ ^ ^ ^ |
* | | | | |
* | | ±----+ ±--------+ |
* | | | | |
* | ±----------+ | |
* | | | | |
* ±-----+ | Module—>(Module) |
* | | ^ ^ |
* OtherClass–>(OtherClass) | | |
* | | |
* Class---->(Class) |
* ^ |
* | |
* ±---------------+
*
* + All metaclasses are instances of the class `Class’.
*/

And of course, all classes are instances of the Class too.

						matz.

I’ve been brooding again on the circularities
in Ruby’s classes.

Now I’m thinking of a particular question:
How would you explain where “new” comes from
in a class?

It’s easy to say that all classes are objects
of the type Class.

So for example, Object has a “new” because it’s
a Class. But on the other hand, Class is an
Object.

Would you say that Object gets “new” from Class,
or vice versa? Or neither? Or should I just not
worry about it?

That’s pretty easy.

“ARGV is an instance of Array, so I can call reverse on it.”
“Object is an instance of Class, so I can call new on it.”

This arose because I was trying to draw a picture
of Ruby’s entire object model.

Comments, anyone? Matz, Dave, Guy, David? Others?

It’s 1:35 a.m. my time. I should go to bed. I’ve
probably said something incorrect in this email.

The main circularity in Ruby is as follows: it’s really easy to use and saves
you haves of time, but then you waste time playing with it.

Hal

Gavin

···

From: “Hal E. Fulton” hal9000@hypermetrics.com

How would you explain where “new” comes from
in a class?

From the Class class.

This arose because I was trying to draw a picture
of Ruby’s entire object model.

Did you check the chart in object.c?

I very rarely look at the source. I was not aware
of the diagram. Thank you.

And of course, all classes are instances of the Class too.

Why does the diagram show these parenthesized names?
I thought that Class was the only true metaclass in
Ruby. Why then do we show things like (Class) and
(Object) in the diagram?

Thanks much,
Hal

···

----- Original Message -----
From: “Yukihiro Matsumoto” matz@ruby-lang.org
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, August 15, 2002 2:23 AM
Subject: Re: Thought question: Where does “new” come from?

Why does the diagram show these parenthesized names?
I thought that Class was the only true metaclass in
Ruby. Why then do we show things like (Class) and
(Object) in the diagram?

(Class) is the singleton class associated with Class
(Object) is the singleton class associated with Object

Guy Decoux

Oh, yes, of course. Where the singleton information
goes.

I am still unclear why these are conceptually
necessary.

If I do a “def Object.foo” why does it have to go into
(Object) as opposed to just Object?

Hal

···

----- Original Message -----
From: “ts” decoux@moulon.inra.fr
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Cc: ruby-talk@ruby-lang.org
Sent: Thursday, August 15, 2002 11:57 AM
Subject: Re: Thought question: Where does “new” come from?

Why does the diagram show these parenthesized names?
I thought that Class was the only true metaclass in
Ruby. Why then do we show things like (Class) and
(Object) in the diagram?

(Class) is the singleton class associated with Class
(Object) is the singleton class associated with Object

I think it is for uniformity’s sake, so you can handle the same way these
situations:
def Object.foo
def anobject.foo
in the second line we really need the singleton class, and, having
implemented this, the first one comes for free.

···

On Fri, Aug 16, 2002 at 02:38:01AM +0900, Hal E. Fulton wrote:

(Class) is the singleton class associated with Class
(Object) is the singleton class associated with Object

Oh, yes, of course. Where the singleton information
goes.

I am still unclear why these are conceptually
necessary.

If I do a “def Object.foo” why does it have to go into
(Object) as opposed to just Object?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
’_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Computers are like air conditioners. Both stop working, if you open windows.
– Adam Heath

Hi –

This has gotten bizarrely long. But I think it’s OK as an
explanation.

Finger crossed, candles lit, gods appeased… here I go.

From: “ts” decoux@moulon.inra.fr
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Cc: ruby-talk@ruby-lang.org
Sent: Thursday, August 15, 2002 11:57 AM
Subject: Re: Thought question: Where does “new” come from?

Why does the diagram show these parenthesized names?
I thought that Class was the only true metaclass in
Ruby. Why then do we show things like (Class) and
(Object) in the diagram?

(Class) is the singleton class associated with Class
(Object) is the singleton class associated with Object

Oh, yes, of course. Where the singleton information
goes.

I am still unclear why these are conceptually
necessary.

If I do a “def Object.foo” why does it have to go into
(Object) as opposed to just Object?

(See Mauricio’s post also.)

If you have:

class Thing
def talk
puts "hi"
end
end

t = Thing.new

you’ve created a situation where t responds to ‘talk’. The basic
principle here is: for obj to respond to meth, meth has to be defined
as an instance method in obj’s class. (Or included module-wise, but
nevermind that.)

Now, let’s say we’d done this instead (starting again here, not
cumulative):

class Thing
end

t = Thing.new

Now, if we do this:

def t.talk
puts "hi"
end
t.talk

we’ve created another situation where t responds to talk. And we know
from the principle stated above that for t to respond to talk, talk
has to be defined as an instance method in t’s class.

Which means that by doing “def t.talk”, we’ve just induced a new
instance method in t’s class.

So now the question is, what is “t’s class”? We don’t really want
"def t.talk" to retroactively make it as if we’d done

class Thing
def talk

since that would have all sorts of effect on all sorts of Things. And
yet… we do want it to be as if we’d been able to do:

Hi, I’m in t’s class, defining instance methods
def talk

This is where the singleton class comes in. It is, by definition,
that-which-is-the-class-of-t-and-only-t. And it serves the purpose
being the class into which we can insert a new method for t, without
having to insert it into Thing.

I have found it helpful to think of the singleton class as being like
a very thin sheet of clear plastic, adhering to the underside of the
object’s (non-singleton) class. Sort of like a stick-on fake tatoo.
From the object’s perspective, looking upward, anything written on the
plastic appears to be written directly on the “official” class. From
the side (for example, when you do “obj.type” or “obj.is_a?”), the
plastic is so thin as to be invisible. All you see is the object and
its non-singleton class. And that class doesn’t know the plastic is
there either.

Finally…

When you do

def Object.foo

you’re doing the same thing: you’re defining a singleton method on the
object Object, and that method’s home is as an instance method in
Object’s singleton class. “Object” here is filling exactly the same
role as “t” in the previous example.

Going back to your question:

If I do a “def Object.foo” why does it have to go into
(Object) as opposed to just Object?

If a method goes into Object, then it becomes a method of things that
are of type Object (or descendants):

class Object
def meth

o = Object.new
o.meth

What you want, however, is for foo to be a method of things that are
of type “the-thing-that-Object-is-a-type-of”. You could of course do
this on a non-singleton basis, since you know that Object is of type
Class:

class Class
def foo

Object.foo

but what the “def obj.meth” syntax does is, as in the ‘t’ example,
define the method as an instance method of the singleton class of the
object (which is Object, in this case).

Post-finally: this is all also why you can do this:

class << t
def talk

It’s another way of accomplishing the “Put me in t’s singleton
superclass so I can define an instance method in it” thing.

David

···

On Fri, 16 Aug 2002, Hal E. Fulton wrote:

----- Original Message -----


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

dblack@candle.superlink.net wrote in message
news:Pine.LNX.4.44.0208151402090.9010-100000@candle.superlink.net

Hi –

This has gotten bizarrely long. But I think it’s OK as an
explanation.

I didn’t track this thread, but today I independently tried to write up the
scoping rules for Ruby. I think they are very complex and difficult to
explain. Any given expression is working in a context of about 5 different
kinds of scope at the same time.

This is perhaps a weakness of Ruby - it makes an otherwise very easy
language very hairy in some aspects. Or is it because of this that most
things are easy - such as being able to have temporary variables in a class
definition?

Below is what I wrote - which ended up being just examples because other
attempts of description got rather complex. Disclaimer - it may not be
correct and the terms are certainly not official Ruby terms.

Mikkel

{chapter Scopes}

{section Introduction}

Ruby is a simple language, except the scopes in the Ruby language can be
somewhat complex.

In a Ruby file it is valid to assign an expression to a variable:

x = 3 * 7

It is also possible to define function (or method or message depending on
terminology):

def foo
y = 2 * 7
end

The variable x assigned outside the function foo is not visible inside the
function. The variable y defined inside the function is not visible outside
the function.

However:

@a = 2

def double_a
@a + @a
end

double_a # -> 4

Variables starting with @ are visible both inside and outside of functions.

This chapter will explain the non-trivial scoping rules of Ruby.

{section Everything is an object}

In Ruby almost everything is an object.

An basic object is a collection of member variables and member functions. At
any member variables and member functions can be added, removed or assigned
/ redefined.

A class has two basic objects: the prototype object and the static object.
In addition a class has child classes and child modules and a base class.

Ruby has some elaborate syntax to access these various objects, but it
really simplifies issues if it is remembered that a class really is two
objects.

class Foo

@a = 2 #this is a static object member variable

def Foo.hello
#this is a static object method
puts @a #same @a as above
end

def bar
# this is a prototype object method
@a = 4
# the prototype access the @a in the instance
# of the object redirecting the call to the prototype.
@@b = 8

#@@b is a member of the prototype object.
#there is only one instance of @@b for the class

# this method cannot directly access members of the
# static object, but it can call static methods:

Foo.bar

end

end

def Foo.world
#this is also a static object method of Foo
#it accesses the same @a as Foo.hello
puts @a + @a
end

a = Foo.new
def a.biz
#this is a method that belongs to a single instance only.
end

Hello –

@a = 2

def double_a
@a + @a
end

double_a # -> 4

Variables starting with @ are visible both inside and outside of functions.

The only place that happens, I think, is at the “top level” of
execution. Otherwise it’s like this:

class Thing
@a = 1
puts “Class scope: @a is >#{@a}<”

def show
  puts "Instance scope: @a is >#{@a}<"
end

end

Thing.new.show

=>
Class scope: @a is >1<
Instance scope: @a is >< # this @a is nil

David

···

On Fri, 16 Aug 2002, MikkelFJ wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi,

I didn’t track this thread, but today I independently tried to write up the
scoping rules for Ruby. I think they are very complex and difficult to
explain. Any given expression is working in a context of about 5 different
kinds of scope at the same time.

I admit Ruby’s scope rules are rather complex, comparing to other part
of Ruby. But things are much simpler than you described. The key is
the scope of the local variables.

Global variables has no scope. You can access them from everywhere.

Instance variables belong to the current value of “self”. “self” may
be switched via instance_eval() etc.

Local variables belong to the current “scope”, which is introduced by
the following statements: class, module, def. In addition, the
toplevel (outside of any of statements above) has its own scope, and
blocks associated with methods have scopes too. Local variabls are
effective from the first assignment in the current scope to the end of
the scope. Local variables that belong to the outer scope cannot be
accessed, except if the current scope is introduced by the block
(the most complex part of the rules).

Constants are searched in the following order. The innermost
class/module, outer class/module to the top, superclasses of the
innermost class.

Class variables belong to the innermost non singleton class.
(the behavior has changed in 1.6.8 and later; this is new one).

						matz.
···

In message “Re: Thought question: Where does “new” come from?” on 02/08/16, “MikkelFJ” mikkelfj-anti-spam@bigfoot.com writes:

“MikkelFJ” wrote in

I didn’t track this thread, but today I independently tried to write up
the
scoping rules for Ruby. I think they are very complex and difficult to
explain. Any given expression is working in a context of about 5 different
kinds of scope at the same time.

I am not sure if I would call the rest of Ruby simple (undoubtedly a
reflection of my own limitations) but I agree with your point that
Ruby’s scoping rules are ``somewhat’’ complex. Learning and
understanding these different scoping rules is probably a big part in
becoming proficient in writing, and even more so, reading
Ruby code. Anyway, I sort of counted seven types of variables or
constants in Ruby.

local variables
dynamic local variables (whatever those may be …?)
thread local variables
instance variables
class variables
global variables
constants

On top of this, there is a subtle interaction and slightly different
scoping rules between normal scope'' andeval scope’’ (for
local variables). In addition, we have method names which
can interfere with local variables or constant names - the most
prominent example being the infamous attr_writer, versus
local variable confusion.

···

class Object
attr_writer :surprise
def surprise_test
surprise = "surprise"
p @surprise
self.surprise = "okay"
p @surprise
end
end

surprise_test

nil

“okay”


This is perhaps a weakness of Ruby - it makes an otherwise very easy
language very hairy in some aspects. Or is it because of this that most
things are easy - such as being able to have temporary variables in a
class
definition?

Yes these ``extra local’’ variables add another level of complexity -
they are great too play around;-) and even better to p…s my time
away;-( …


t = "changed"
s = "changed"
A = Class.new {
define_method(:outer_t=) {|s,| t =s }
define_method(:outer_t) { puts t }
}

class A
t = "unchanged"
define_method(:inner1_t) { puts t }
end

class A
t = "changed"
define_method(:inner2_t= ) {|s,| s,t = t,s; t }
define_method(:inner2_t) { puts t }
class << A; self end.
send(:define_method,:inner2_t) { puts t }
end

a = A.new
a.outer_t = "outer"
a.inner2_t = “inner”

a.outer_t # outer
a.inner1_t # unchanged
a.inner2_t # inner
A.inner2_t # inner
p [s,t] # [“outer”, “outer”]

Below is what I wrote - which ended up being just examples because other
attempts of description got rather complex. Disclaimer - it may not be
correct and the terms are certainly not official Ruby terms.

However:

@a = 2

def double_a
@a + @a
end

double_a # -> 4

Variables starting with @ are visible both inside and outside of
functions.

Actually this has a fairly simple explanation. The double_a'' declaration on themain scope’’ defines a private Object
instance method available for the ``main’’ or any other object

  • e.g.

p $main = self # main

def double_a
puts @a + " : " + @a
end

p Object.private_instance_methods # [“double_a”, “initialize”]
p $main.singleton_methods # [“public”, “include”, “private”, “to_s”]

public :double_a

@a = "$main @a doubled is"
1.instance_eval { @a = “1 @a doubled is” }

double_a # $main @a doubled is : $main @a doubled is
$main.double_a # $main @a doubled is : $main @a doubled is
1.double_a # @a doubled is : 1 @a doubled is


Of course this begs the question why Matz didn’t simply set

      $main = Object or  possibly  $main = Kernel?

This chapter will explain the non-trivial scoping rules of Ruby.

In the end the scoping rules for instance, class variables (at least
their recent behavior) and constant are actually fairly logical and
consistent. On the hand, the scoping rules for local variable
are imo the least satisfying ones.

class Foo

@a = 2 #this is a static object member variable

def Foo.hello
#this is a static object method
puts @a #same @a as above
end

You are mixing many different issues here. Declaring, changing
and using instance and/or class variables, and declaring instance
and/or singleton methods - e.g.


class Class
@a = "Class @a"
def hello
@a
end
end

def Object.world
puts @a + " : " + @a
end

class Foo
@@a = "Foo a@@"
def bar
@a = “Foo inst @a"
puts [Foo.hello,Bar.hello, Foo.bar].join(”, ")
end
end

Foo.instance_eval { @a = “Foo @a” }

class Bar
@@a = “Bar @@a
@a = "Bar @a"
def Foo.bar
@@a
end
end

Class.world # Class @a : Class @a
Foo.world # Foo @a : Foo @a
Bar.world # Bar @a : Bar @a
Foo.new.bar # Foo @a, Bar @a, Bar @@a

/Christoph

dblack@candle.superlink.net wrote in message
news:Pine.LNX.4.44.0208151905140.9567-100000@candle.superlink.net

Variables starting with @ are visible both inside and outside of
functions.

The only place that happens, I think, is at the “top level” of
execution. Otherwise it’s like this:

Yes - when writing it I was seeking a conclusion - and I didn’t really catch
this difference and the subsequent section I wrote deals with relating
static methods to class scope variables.

It somehow seems like a bug because each file can be viewed as a class
definition of the same root level class. This would be consistent except for
the mentioned behaviour.

def Thing.static_show
puts "Static class scope: @a is >#{@a}<"
end

The functions where @a at class scope is visible, are the static class
methods.

class Thing
@a = 1
puts “Class scope: @a is >#{@a}<”

 def show
   puts "Instance scope: @a is >#{@a}<"
 end

end

def Thing.static_show
puts "Instance scope: @a is >#{@a}<"
end

Thing.new.show
Thing.static_show

=>

Class scope: @a is >1<
Instance scope: @a is ><
Static scope: @a is >1<

Hi –

dblack@candle.superlink.net wrote in message
news:Pine.LNX.4.44.0208151905140.9567-100000@candle.superlink.net

Variables starting with @ are visible both inside and outside of
functions.

The only place that happens, I think, is at the “top level” of
execution. Otherwise it’s like this:

Yes - when writing it I was seeking a conclusion - and I didn’t really catch
this difference and the subsequent section I wrote deals with relating
static methods to class scope variables.

It somehow seems like a bug because each file can be viewed as a class
definition of the same root level class. This would be consistent except for
the mentioned behaviour.

The availability of instance variables (@var) depends on what "self"
is at a given point – that is, what instance’s variables you’re
trying to access. At the top level, “self” is a bootstrapping default
Object (if that’s a good way to put it), and the scope is “flattened”,
so that there’s no change inside a method definition:

irb(main):002:0> p id
537806448
nil
irb(main):003:0> def thing; p id; end
nil
irb(main):004:0> thing
537806448
nil

It doesn’t behave like a class definition, because it isn’t one :slight_smile:
There’s nothing here to instantiate.

However, when you do define a class, the scope of the class and the
scope of its eventual objects is different:

irb(main):005:0> class Thing; p id; def thing; p id; end; end
537854410
nil
irb(main):006:0> Thing.new.thing
537850560
nil

def Thing.static_show
puts "Static class scope: @a is >#{@a}<"
end

The functions where @a at class scope is visible, are the static class
methods.

That’s true of all instances of objects: when the object is “self”,
you can see its instance variables:

irb(main):001:0> class Thing; def talk; @a = 10; puts @a; end; end
nil
irb(main):002:0> t = Thing.new
#Thing:0x4019b9d0
irb(main):003:0> t.talk
10
nil
irb(main):004:0> def t.singleton_method; puts @a; end
nil
irb(main):005:0> t.singleton_method
10

In this example, you can see @a from singleton_method because, during
the definition of this method, t is “self”. That’s exactly what’s
happening when you do:

def Thing.whatever

During that definition, you can see Thing’s instance variables, if
any.

class Thing
@a = 1
puts “Class scope: @a is >#{@a}<”

 def show
   puts "Instance scope: @a is >#{@a}<"
 end

end

def Thing.static_show
puts “Instance scope: @a is >#{@a}<”

Was that supposed to be “Static scope”? (It is in the output :slight_smile:

end

Thing.new.show
Thing.static_show

=>

Class scope: @a is >1<
Instance scope: @a is ><
Static scope: @a is >1<

Basically any object can have instance variables; there’s no
connection between one objects @a and another’s – even if the second
object is an instance of the first.

I’m just wondering… I know you mentioned in your last post that you
weren’t using standard Ruby terminology. Why not? :slight_smile: Personally I
don’t find the term “static” to be helpful; it seems to obscure the
underlying similarity of the mechanism, and how consistent they are
within and among objects (classes and others). I suppose the same
could be said, in a sense, of the term “class method”, since there’s
no special term for the singleton methods of other specific types of
object. Anyway, like I said, just wondering :slight_smile:

David

···

On Fri, 16 Aug 2002, MikkelFJ wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

def Thing.static_show
puts “Instance scope: @a is >#{@a}<”

Was that supposed to be “Static scope”? (It is in the output :slight_smile:

Yeah :slight_smile:

Several of you have said that instances depend on the value of self. But
that is the key of the “problem”. What exactly is self. In a class
definition there seems to be the class itself, and then there is a default
instance which is current value of “self”. The class a such does not appear
as self, nonetheless it is part of the scope - it is this construct I dubbed
the prototype object.

class Thing
@a = 1
end
class <<Thing
@a = 2
puts self
end

=> Class

(Elaborate on this example) - instance variables in << Thing doesn’t appear
to be globally shared nor avaible to Thing methods. (But then I’m currently
running 1.6.6 and 1.6.8 is changed I hear).

I’m just wondering… I know you mentioned in your last post that you
weren’t using standard Ruby terminology. Why not? :slight_smile:

To be honest because I didn’t bother to open the litterature, I was just
trying to formulate it to myself. Anyway, the term static is the closest you
get to similar constructs in languages like Java and C++.

Personally I

don’t find the term “static” to be helpful; it seems to obscure the
underlying similarity of the mechanism, and how consistent they are
within and among objects (classes and others). I suppose the same
could be said, in a sense, of the term “class method”, since there’s
no special term for the singleton methods of other specific types of
object. Anyway, like I said, just wondering :slight_smile:

The “problem” (if it is a problem) I have with “class method” is that any
normally defined method belongs to the class, as opposed to singleton
methods that belongs to the instance. Hence I see the normal methods as
class methods. The “static” methods belongs to a separate default created
instance with the same name as the class. This default instance is
statically allocated at the time the class is first defined. Hence the term
static method.

Mikkel

(Elaborate on this example) - instance variables in << Thing doesn't appear
to be globally shared nor avaible to Thing methods. (But then I'm currently
running 1.6.6 and 1.6.8 is changed I hear).

If you want to make reference to [ruby-talk:47388] more precisely to this,
be carefull

Class variables belong to the innermost *non singleton* class.
(the behavior has changed in 1.6.8 and later; this is new one).

If I'm right when matz make reference to "class variables", he make
reference to @@var

For example

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   class << self
      @@a = 12
   end
   p @@a
end
pigeon%

with 1.6.7 the class variable is defined in the singleton class

pigeon% /usr/bin/ruby -v b.rb
ruby 1.6.7 (2002-03-01) [i686-linux]
b.rb:4: warning: declaring singleton class variable
b.rb:6: uninitialized class variable @@a in A (NameError)
pigeon%

with 1.7.2 the class variable is defined in the innermost *non singleton*
class. in my example in A

pigeon% ./ruby -v b.rb
ruby 1.7.2 (2002-08-06) [i686-linux]
12
pigeon%

Guy Decoux

The “problem” (if it is a problem) I have with “class
method” is that any normally defined method belongs to
the class, as opposed to singleton methods that belongs
to the instance. Hence I see the normal methods as class
methods. The “static” methods belongs to a separate
default created instance with the same name as the
class. This default instance is statically allocated at
the time the class is first defined. Hence the term
static method.

Normally defined methods are called instance methods. Their
definitions are held by the class object, but they are only applicable
to instances of that class.

Class methods (what you call static) are methods that are applicable
to the class.

class A
def imethod() end
def A.cmethod() end
end

A.instance_methods #=> [“imethod”]
A.methods #=> [“cmethod”, “new”, “superclass”, “private_instance_methods”, “clone”, … ]

The term “static” is misleading. Static (as used in Java and C++)
refers to stand-alone functions that are in the scope of a class, but
can be invoked without any reference to an object instance. No such
thing exists in Ruby.

···


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

For example

pigeon% cat b.rb
#!/usr/bin/ruby
class A
class << self
@@a = 12
end
p @@a
end
pigeon%

with 1.6.7 the class variable is defined in the singleton class

pigeon% /usr/bin/ruby -v b.rb
ruby 1.6.7 (2002-03-01) [i686-linux]
b.rb:4: warning: declaring singleton class variable
b.rb:6: uninitialized class variable @@a in A (NameError)
pigeon%

Actually I get “12” and no error using 1.6.6 on Windows.
In the following the ruby interpreter yields a parse error in class B at the
line @@a = “hello” in class B. I irb I get “hello” printed. At some point I
was required to assign @@a as in class C or I would get a not initialized
error, but I no longer remember how because now class C works.

Anyway I don’t think I’ll bother more with that before there is a 1.6.8
release for Windows.

puts "— A —"
class A
class << self
@@a = 12
end
p @@a
end
puts "— B —
class B
end
class << B
def hello
@@a = "hello"
end
end
B.hello
puts "— C —"
class C
@@a = "hello"
end
def C.hello
@@a = "hello"
end
C.hello

Thanks for the clarification.

The term “static” is misleading. Static (as used in Java and C++)
refers to stand-alone functions that are in the scope of a class, but
can be invoked without any reference to an object instance. No such
thing exists in Ruby.

This isn’t exactly true. The C++ class can have static data members. If you
like, you can call these part of the static object instance. You can call
the functions without a reference to an instance because the compiler
implicitly knows the location of the static instance, still you give the
name of class, just as you do in Ruby. When I use the term static it relates
to the statically allocated nature (or preallocated globally known nature).

Mikkel

Actually I get "12" and no error using 1.6.6 on Windows.

This is because 1.6.6 use another rule :slight_smile:

With 1.6.6, ruby use the current class : if this class is a singleton class
then it retrieve the class associated with it and define the class
variable in this class

In the following the ruby interpreter yields a parse error in class B at the
line @@a = "hello" in class B.

This is because you have a bug in your code :slight_smile:

puts "--- A ---"
class A
   class << self
      @@a = 12
   end
   p @@a
end
puts "--- B ---

                  ^
                  >
Missing " here

Guy Decoux