# Why does this code traversing iv\_tbl using dl/struct via evi

**URL:** <https://www.ruby-forum.com/t/why-does-this-code-traversing-iv-tbl-using-dl-struct-via-evi/63675>\
**Category:** Ruby\
**Created:** [June 17, 2006, 2:12pm UTC](https://www.ruby-forum.com/t/why-does-this-code-traversing-iv-tbl-using-dl-struct-via-evi/63675 "2006-06-17T14:12:20Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rob\_Pitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/76d3ee/32.png) [@Rob\_Pitt](https://www.ruby-forum.com/u/Rob_Pitt)\
**Post date:** [June 17, 2006, 2:12pm UTC](https://www.ruby-forum.com/t/why-does-this-code-traversing-iv-tbl-using-dl-struct-via-evi/63675/1 "2006-06-17T14:12:20Z")

</div>

Hi all,

I seem to have misunderstood some finer point of how the instance  
variable tables work. Since for something like this I expect code  
speaks louder than words, I have made a small test case using evil.rb  
(to keep the file size down) available from:

[http://rubyforge.org/cgi-bin/viewvc.cgi/evil/lib/evil.rb](http://rubyforge.org/cgi-bin/viewvc.cgi/evil/lib/evil.rb)?  
revision=1.44&root=evil

Unfortunately, due to some error I have made this test case does not  
find all the instance variable keys. I’m sure some wizard out there  
will easily spot my newbie mistake. Could someone please point out  
where I’m going wrong by making this tiny test case work?

Many thanks,

Rob.

---

<div class="post-metadata">

**Author:** ![Rob\_Pitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/76d3ee/32.png) [@Rob\_Pitt](https://www.ruby-forum.com/u/Rob_Pitt)\
**Post date:** [June 19, 2006, 10:46am UTC](https://www.ruby-forum.com/t/why-does-this-code-traversing-iv-tbl-using-dl-struct-via-evi/63675/2 "2006-06-19T10:46:12Z")

</div>

Rob Pitt schrieb:

> I seem to have misunderstood some finer point of how the instance  
> variable tables work. (…) Could someone please point out where I’m  
> going wrong by making this tiny test case work?

Rob, I added the necessary changes to your code below:

> require ‘evil’  
> require ‘test/unit’

module RubyInternal  
ST\_TABLE\_BIN = struct [  
“ST\_TABLE\_ENTRY \*entry”  
]  
end

> ```
> a.instance_variable_set(key,1)
> end
> r_object = RObject.new(a.internal_ptr)
> table = ST_TABLE.new(r_object.iv_tbl)
> chain = 0
> while chain < table.num_bins
> 
> ```

replace the following line:

> ```
> table_entry = ST_TABLE_ENTRY.new(table.bins + (chain * DL::sizeof('P')))
> 
> ```

with:

```
     table_bin = ST_TABLE_BIN.new(table.bins + (chain * 

```

DL::sizeof(‘P’)))  
table\_entry = table\_bin.entry &&  
ST\_TABLE\_ENTRY.new(table\_bin.entry)

> ```
> while table_entry
> sym = table_entry.key.to_sym 
> located_keys << sym.to_s if sym && sym.to_s[0] == ?@
> table_entry = table_entry.next && ST_TABLE_ENTRY.new(table_entry.next)
> end
> chain += 1
> end
> assert_equal(created_keys.sort,located_keys.sort)
> 
> ```
> 
> end  
> end

“table.bins” points to an array of “table.num\_bins” pointers to table  
entries. So

table.bins + (chain \* DL::sizeof(‘P’))

isn’t the address of a table entry, but the address of a pointer to a  
table  
entry. In order to dereference these pointers, I added the ST\_TABLE\_BIN  
struct  
to your code.

Regards,  
Pit
