# Definition of methods: self

**URL:** <https://www.ruby-forum.com/t/definition-of-methods-self/102965>\
**Category:** Ruby\
**Created:** [July 8, 2006, 11:15pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965 "2006-07-08T23:15:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 8, 2006, 11:15pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/1 "2006-07-08T23:15:25Z")

</div>

In Why’s poignant guide to Ruby some examples appear where he defines a  
class “class LotteryTicket”, and then he defines a method “def  
self.new\_random”, or “def LotteryDraw.buy(…)”; that is, before the name  
of the method, the name of the class appears (the name or the keyword  
“self”). However, in other methods in the other classes, the class name  
is not set before the name of the method. Explanations? 😃

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 8, 2006, 11:37pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/2 "2006-07-08T23:37:08Z")

</div>

Um…wait…Do I have to set the name of the class before the name of  
the method when this method is a class method (except the “initialize”)?

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 8, 2006, 11:53pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/3 "2006-07-08T23:53:15Z")

</div>

2006/7/8, Damaris F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Um…wait…Do I have to set the name of the class before the name of  
> the method when this method is a class method (except the “initialize”)?

Right, but no exception: initialize is an instance method. new is a  
class method and after a new instance is allocated initialize is  
called on that instance:

$ ruby -e ‘set\_trace\_func lambda {|\*a| p a}; Array.new’  
[“line”, “-e”, 1, nil, #Binding:0x100f6938, false]  
[“c-call”, “-e”, 1, :new, #Binding:0x100f68f0, Class]  
[“c-call”, “-e”, 1, :initialize, #Binding:0x100f6698, Array]  
[“c-return”, “-e”, 1, :initialize, #Binding:0x100f6650, Array]  
[“c-return”, “-e”, 1, :new, #Binding:0x100f6518, Class]

Note, there is also allocate (class method) that will create an empty  
instance of the correct type. So new can be imagined as being  
implemented like this:

class Class  
def new(\*a,&b)  
o = allocate  
o.initialize(\*a,&b)  
o  
end  
end

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 8, 2006, 11:56pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/4 "2006-07-08T23:56:44Z")

</div>

Damaris F. wrote:

> Um…wait…Do I have to set the name of the class before the name of  
> the method when this method is a class method (except the “initialize”)?

Yes. this is the class method declaration syntax. Within class body  
definition the default receiver is the class itself, so the snippets  
beneath are equivalent:

class A  
def A.meth  
end  
end

class A  
def self.meth  
end  
end

If there are more class methods in a class it is easier to switch to  
class instance:

class B  
class \<\< self

```
     def meth1
     end

# more methods
 end

```

end

or even:

class B  
instance\_eval do

```
     def meth1
     end

# more methods
 end

```

end

lopex

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 9, 2006, 4:43pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/5 "2006-07-09T16:43:07Z")

</div>

Ok, thanks for the explanations!  
But…now that you mention the concatenator… I will comment another  
problem in this entry. (I write all the code, ven though perhaps you  
don’t need it)

The problem here is that the re- definition ot a class (LotteryDraw)  
doesn’t seem to see the attributes of the first definition.

I have the class ot the lottery ticket:

* * *

class LotteryTicket  
NUMERIC\_RANGE = 1…25  
attr\_reader :picks

def initialize( \*picks )  
[…]  
@picks = picks  
end

def score( final )  
count = 0  
final.picks.each do |note|  
count +=1 if picks.include? note  
end  
count  
end

end

* * *

Now I have the lottery draw, where I store the buyers of the tickets:

* * *

class LotteryDraw  
@@tickets = {}  
def LotteryDraw.buy( customer, \*tickets )  
unless @@tickets.has\_key?( customer )  
@@tickets[customer] = []  
end  
@@tickets[customer] += tickets  
end  
end

* * *

And NOW, I REDEFINE THE CLASS with the concatenator, adding a new class  
method:

* * *

class \<\< LotteryDraw  
def play  
final = LotteryTicket.new\_random  
winners = {}  
@@tickets.each do |buyer, ticket\_list|  
ticket\_list.each do |ticket|  
score = ticket.score( final )  
next if score.zero?  
winners[buyer] ||= []  
winners[buyer] \<\< [ticket, score]  
end  
end  
@@tickets.clear  
winners  
end  
end

* * *

And now I execute the following:

* * *

LotteryDraw.buy(‘JuanMi’,  
LotteryTicket.new( 12, 6, 19 ),  
LotteryTicket.new( 5, 1, 3 ),  
LotteryTicket.new( 24, 6, 8 ))

LotteryDraw.buy(‘Da’,  
LotteryTicket.new( 18, 4, 7 ),  
LotteryTicket.new( 21, 25, 3 ),  
LotteryTicket.new( 12, 17, 19 ))

LotteryDraw.play.each do |winner, tickets|  
puts winner + “won on " + tickets.length + " ticket(s)!”  
tickets.each do |ticket, score|  
puts “\t” + ticket.picks.join( ', ’ ) + ": " + score  
end  
end

* * *

And an exception arises:  
in `play’: uninitialized class variable @@tickets in Object.  
This exception appears in the trace:

- LotteryDraw.play.each do |winner, tickets|,
- @@tickets.each do |buyer, ticket\_list| (in LotteryDraw.play)

What is the problem? Thanks (and sorry if this is very long :()

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 9, 2006, 7:30pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/6 "2006-07-09T19:30:58Z")

</div>

Damaris F. wrote:

> class LotteryTicket  
> final.picks.each do |note|  
> class LotteryDraw  
> method:  
> winners[buyer] \<\< [ticket, score]  
> LotteryDraw.buy(‘JuanMi’,  
> puts winner + “won on " + tickets.length + " ticket(s)!”
> 
> - @@tickets.each do |buyer, ticket\_list| (in LotteryDraw.play)
> 
> What is the problem? Thanks (and sorry if this is very long :()

Without looking too closely at your code I’m guessing that it’s because  
your class methods are in the singleton class of LotteryDraw - and so  
lookups for class variables are done in _that_ hierarchy and not in the  
one of LotteryDraw.

I generally recommend to not use class variables because they introduce  
all sorts of weirdnesses. I’d rather use a normal instance variable of  
the class instance. That’s accessible for sure in the singleton method.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 11, 2006, 4:13pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/7 "2006-07-11T16:13:43Z")

</div>

I agree with Robert - avoid @@class\_variables wherever possible. The  
problem is the way @@class\_variables are looked up - they are shared  
within a class hierarchy. Also, class \<\< LotteryDraw does not  
introduce a new class definition scope (even though you may think it  
looks like it should).

The following examples demonstrate the way lookup for class variables  
works in the context you’re using:

class A  
@@a = 42  
end

# add a class variable to Object - without this, the next puts @@a

would cause an error  
@@a = 24  
class \<\< A  
puts @@a # this refers to the toplevel Object @@a, not A’s  
end

class A  
puts @@a # this does refer to A’s @@a  
end

p @@a

**END**  
24  
42  
24

(By the way, if you had run ruby with -w you would have got the warning:  
class variable access from toplevel singleton method  
)

Also, the order in which you define @@class\_variables matters. Look at  
this example:

@@a = 24 # add a class variable to Object  
class A  
@@a = 42

# because @@a already exists in the class hierarchy (A inherits from

Object)

# this assignment updates it

end

class \<\< A  
puts @@a # there is only one @@a now  
end

class A  
puts @@a  
end

p @@a

**END**  
42  
42  
42

My advice is steer clear of them!

Regards,

Sean

---

<div class="post-metadata">

**Author:** ![damaris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/2bfe46/32.png) [@damaris](https://www.ruby-forum.com/u/damaris)\
**Post date:** [July 21, 2006, 6:42pm UTC](https://www.ruby-forum.com/t/definition-of-methods-self/102965/8 "2006-07-21T18:42:32Z")

</div>

Yes, thank you all, boys. I had set the class\<\< LotteryDraw as a new  
class definition. Now, I’ve set the class\<\<LotteryDrwa inside the  
LotteryDraw itself and it already works. Thanks. And thanks for the  
other comments.
