# Packaging hybrid extension?

**URL:** <https://www.ruby-forum.com/t/packaging-hybrid-extension/71561>\
**Category:** Ruby\
**Created:** [October 9, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561 "2006-10-09T23:04:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rykkers](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e5b9ba/32.png) [@rykkers](https://www.ruby-forum.com/u/rykkers)\
**Post date:** [October 9, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561/1 "2006-10-09T23:04:58Z")

</div>

I’m writing something which is partially written in ruby, but uses an  
extension which adds methods to some of the classes in the ruby part.

Right now I’ve got a directory which contains both the ruby code and  
the so containing the extensions

$ls  
mycode.rb mycode\_prims.so

in mycode.rb I’ve got something like:

class Mycode  
def foo  
end  
end

# link in the primitives, mycode\_prims includes various calls to

# rb\_define\_method to add methods to the Mycode class.

require ‘mycode\_prims’

Now this works if the directory containing both parts is the current  
directory, but not otherwise. Actually I guess it would work as long  
as the directory was on the load path, but I’m concerned about the  
possibility of loading the wrong mycode\_prims.so.

Is there a way to get the directory containing the current source  
file? **FILE** only gives the file name, but not the path.

What is the right way to do this? I’d like to know how to approach  
this either with the code packaged as a gem or as ‘source’.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![rykkers](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e5b9ba/32.png) [@rykkers](https://www.ruby-forum.com/u/rykkers)\
**Post date:** [October 9, 2006, 11:28pm UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561/2 "2006-10-09T23:28:59Z")

</div>

On Tue, 10 Oct 2006, Rick DeNatale wrote:

> directory, but not otherwise. Actually I guess it would work as long  
> as the directory was on the load path, but I’m concerned about the  
> possibility of loading the wrong mycode\_prims.so.
> 
> Is there a way to get the directory containing the current source  
> file? **FILE** only gives the file name, but not the path.
> 
> What is the right way to do this? I’d like to know how to approach  
> this either with the code packaged as a gem or as ‘source’.

one idea is to do something like this

in foo.rb

require ‘rbconfig’

arch = Config::CONFIG[“arch”]  
dlext = Config::CONFIG[“DLEXT”]

this = File.dirname **FILE**  
archdir = File.join this, arch

lib = File.join archdir, “foo.#{ dlext }”  
require lib

then you layout dirs like so

lib/foo.rb  
lib/i686-linux/foo.so  
lib/mswin/foo.dll

and you can distribute one gem, one tarball, etc. you also could just  
dump  
the \*.so right into the libdir and do a

lib = File.join(File.dirname( **FILE** ), “foo.#{ dlext }”)  
require lib

for example. the key point is to bury the native lib close to the \*.rb  
file  
and do a relative require.

hope that made sense…

-a

---

<div class="post-metadata">

**Author:** ![rykkers](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e5b9ba/32.png) [@rykkers](https://www.ruby-forum.com/u/rykkers)\
**Post date:** [October 10, 2006, 3:15am UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561/3 "2006-10-10T03:15:19Z")

</div>

On Tue, 10 Oct 2006, Rick DeNatale wrote:

> File.dirname( **FILE** ) =\> ‘.’  
> na. it’s always relative to the current directory, so you just need to  
> expand  
> it (i forgot this part - sorry)

mussel:~ \> cat /tmp/b.rb  
puts File.dirname(( **FILE** ))

mussel:~ \> ruby /tmp/b.rb  
/tmp

mussel:~ \> cat /tmp/a.rb  
puts File.dirname(File.expand\_path( **FILE** ))

mussel:~ \> ruby /tmp/b.rb  
/tmp

mussel:~ \> ruby -I/tmp -r a.rb -e nil  
/tmp

i use this technique all over the place for relative requires:

[http://codeforpeople.com/lib/ruby/rq/rq-2.3.4/lib/rq-2.3.4.rb](http://codeforpeople.com/lib/ruby/rq/rq-2.3.4/lib/rq-2.3.4.rb)

sorry for confusion.

cheers.

-a

---

<div class="post-metadata">

**Author:** ![rykkers](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e5b9ba/32.png) [@rykkers](https://www.ruby-forum.com/u/rykkers)\
**Post date:** [October 10, 2006, 5:05am UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561/4 "2006-10-10T05:05:29Z")

</div>

On 10/9/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > The problem is that **FILE** only has the file name, not the path, so  
> > mussel:~ \> ruby /tmp/b.rb  
> > mussel:~ \> ruby -I/tmp -r a.rb -e nil  
> > /tmp
> 
> i use this technique all over the place for relative requires:
> 
> [http://codeforpeople.com/lib/ruby/rq/rq-2.3.4/lib/rq-2.3.4.rb](http://codeforpeople.com/lib/ruby/rq/rq-2.3.4/lib/rq-2.3.4.rb)
> 
> sorry for confusion.

Excellent! Thanks Ara.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![rykkers](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e5b9ba/32.png) [@rykkers](https://www.ruby-forum.com/u/rykkers)\
**Post date:** [October 10, 2006, 2:55am UTC](https://www.ruby-forum.com/t/packaging-hybrid-extension/71561/5 "2006-10-10T02:55:18Z")

</div>

On 10/9/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> this = File.dirname **FILE**  
> archdir = File.join this, arch
> 
> lib = File.join archdir, “foo.#{ dlext }”  
> require lib

The problem is that **FILE** only has the file name, not the path, so

File.dirname( **FILE** ) =\> ‘.’

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)
