# How do I intercept creation of fundatmental types, eg. \[\]

**URL:** <https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446>\
**Category:** Ruby\
**Created:** [June 21, 2007, 10:28pm UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446 "2007-06-21T22:28:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 21, 2007, 10:28pm UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/1 "2007-06-21T22:28:26Z")

</div>

Hi,

I’m new to ruby and I love the introspection and metaprogramming  
capabilities. However, I’m having a problem. I want to count the number  
of arrays created. I can only intercept and redefine explicit calls to  
Array.new

For example, I can catch this:

b = Array.new

but I cannot catch this:

x = [3,4,5]

It seems like I should be able to do it with the awesome power of ruby  
:), but I can’t figure out how.

Here is a simple program I am using to try to intercept the creation of  
Array (I’ve tried catching “[]”, initialize, new and clone - I also  
tried overriding Object.new, but couldn’t get that to work either, but  
that code is not included). You’ll notice little newbie commented  
questions sprinkled in the code.

The count variable should be 4 because I make 4 arrays. How do I get  
that?

Thanks in advance!

#! /usr/bin/env ruby

class Array

@@count = 0

# How do I alias Array.new?

# alias orig\_new method(‘Array.new’)

# this doesn’t work either

# orig\_new = method(‘Array.new’)

def Array.new(\*args,&block)  
print “In Array.new”  
print " with #{args.inspect}" if args  
print " and #{block.inspect}" if block  
print “\n”  
print “\tself.class is #{self.class}\n”  
@@count += 1  
puts “\tcount is now #{@@count}”  
#orig\_new  
# Is this right?  
super  
end

# this alias does not work

# how do refer to this method “[]”?

# alias orig\_ob\_cb method(’[]’)

# def [](\*args, &block)

# puts “In [] … We never seem to get here.”

# # this is probably the method for elem = array[]

# # a right hand side assignment

# orig\_ob\_cb(\*args, &block)

# end

alias orig\_clone clone  
def clone  
puts “In clone … Nope we’re not cloning.”  
orig\_clone  
end

alias orig\_initialize initialize  
def initialize(\*args, &block)  
puts “An Array was just initialized!”  
orig\_initialize(\*args, &block)  
end

def count  
@@count  
end  
end

x = [3,4,5]  
puts “x.class is #{x.class}”

# notice we have the count attribute, but we never called new

puts “count is #{x.count}”  
puts “x is #{x.inspect}”

puts “”  
a = Array.new 2, :a  
puts “a.class is #{a.class}”  
puts “count is #{a.count}”  
a \<\< 7  
puts “a is #{a.inspect}”

puts “”  
b = Array.new 3,3  
puts “b.class is #{b.class}”  
puts “count is #{b.count}”  
b[0] = 7  
puts “b is #{b.inspect}”  
puts “b[0] is #{b[0]}”

puts “”  
c = []  
puts “c.class is #{c.class}”  
puts “count is #{c.count}”  
puts “c is #{c.inspect}”

---

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 21, 2007, 10:36pm UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/2 "2007-06-21T22:36:40Z")

</div>

How i use pointer in ruby?

2007/6/21, Durant S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 21, 2007, 10:39pm UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/3 "2007-06-21T22:39:41Z")

</div>

On Fri, 22 Jun 2007 05:28:24 +0900, “Durant S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> For example, I can catch this:
> 
> b = Array.new
> 
> but I cannot catch this:
> 
> x = [3,4,5]
> 
> It seems like I should be able to do it with the awesome power of ruby  
> :), but I can’t figure out how.

It isn’t possible without modifying the interpreter; in the latter case,  
the array is created directly by the interpreter, rather than via a  
method call.

-mental

---

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 21, 2007, 10:45pm UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/4 "2007-06-21T22:45:41Z")

</div>

MenTaLguY wrote:

> > :), but I can’t figure out how.
> 
> It isn’t possible without modifying the interpreter; in the latter case,  
> the array is created directly by the interpreter, rather than via a method call.

And there are other non-method sources of arrays:

def mkary  
return 1,2,3  
end

GC.start  
p ObjectSpace.each\_object(Array){}

a = mkary  
p ObjectSpace.each\_object(Array){}  
b = mkary  
p ObjectSpace.each\_object(Array){}

def mkary2(\*args)  
args  
end

c = mkary2 4,5,6  
p ObjectSpace.each\_object(Array){}  
d = mkary2 7,8,9  
p ObjectSpace.each\_object(Array){}

GC.start  
p ObjectSpace.each\_object(Array){}

---

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 22, 2007, 1:23am UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/5 "2007-06-22T01:23:54Z")

</div>

MenTaLguY wrote:

> On Fri, 22 Jun 2007 05:28:24 +0900, “Durant S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > For example, I can catch this:
> > 
> > b = Array.new
> > 
> > but I cannot catch this:
> > 
> > x = [3,4,5]
> > 
> > It seems like I should be able to do it with the awesome power of ruby  
> > :), but I can’t figure out how.
> 
> It isn’t possible without modifying the interpreter; in the latter case,  
> the array is created directly by the interpreter, rather than via a  
> method call.
> 
> -mental

Ah, that’s too bad. I was encouraged by seeing the count method show up  
in the “x = [3,4,5]” example

Thanks, all.

ps - I figured out how to save and call Array.new below. Fortunately,  
though I’m not sure why, this doesn’t cause infinite recursion.

class Array

@@count = 0

orig\_new = %s{Array.new}

def Array.new(\*args,&block)  
print “In Array.new”  
print " with #{args.inspect}" if args  
print " and #{block.inspect}" if block  
print “\n”  
print “\tself.class is #{self.class}\n”  
@@count += 1  
puts “\tcount is now #{@@count}”  
#super  
orig\_new(\*args,&block)  
end

# …

end

---

<div class="post-metadata">

**Author:** ![mobiledurant](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/73ab20/32.png) [@mobiledurant](https://www.ruby-forum.com/u/mobiledurant)\
**Post date:** [June 22, 2007, 1:52am UTC](https://www.ruby-forum.com/t/how-do-i-intercept-creation-of-fundatmental-types-eg/107446/6 "2007-06-22T01:52:21Z")

</div>

Durant S. wrote:

> ps - I figured out how to save and call Array.new below. Fortunately,  
> though I’m not sure why, this doesn’t cause infinite recursion.
> 
> class Array
> 
> @@count = 0
> 
> orig\_new = %s{Array.new}
> 
> def Array.new(\*args,&block)  
> print “In Array.new”  
> print " with #{args.inspect}" if args  
> print " and #{block.inspect}" if block  
> print “\n”  
> print “\tself.class is #{self.class}\n”  
> @@count += 1  
> puts “\tcount is now #{@@count}”  
> #super  
> orig\_new(\*args,&block)  
> end
> 
> # …
> 
> end

Sorry, that does not work … I was inheriting an orig\_new in “class  
Class” which is not shown here.

This is what I had:

class Class  
alias\_method :orig\_new, :new  
def new(\*args,&block)  
result = orig\_new(\*args,&block)  
print “In Class.new”  
print " with #{args.inspect}" if args  
print " and #{block.inspect}" if block  
print “\n”  
print “\tresult.class is #{result.class}\n”  
result  
end  
end

class Array

@@count = 0

orig\_new = %s{Array.new}

def Array.new(\*args,&block)  
print “In Array.new”  
print " with #{args.inspect}" if args  
print " and #{block.inspect}" if block  
print “\n”  
print “\tself.class is #{self.class}\n”  
@@count += 1  
puts “\tcount is now #{@@count}”  
#super  
orig\_new(\*args,&block)  
end

# …

end

and I thought it was working…
