RB_USER_INSTALL to the rescue
If you try to install gems with extensions as non-root user, you will fail (in general)!
For example, installing hpricot results in the following error message on my FreeBSD 7.2 machine:
make install /usr/bin/install -c -o root -g wheel -m 0755 hpricot_scan.so /home/username/GEMS/gems/hpricot-0.8.1/lib install: /home/username/GEMS/gems/hpricot-0.8.1/lib/hpricot_scan.so: chown/chgrp: Operation not permitted *** Error code 71
The file rbconfig.rb contains some info how you're ruby version has been built.
$ pkg_info -L ruby-1.8.\* | grep rbconfig.rb /usr/local/lib/ruby/1.8/i386-freebsd7/rbconfig.rb
It containes the following interessting line:
CONFIG["INSTALL"] = ENV['RB_USER_INSTALL'] ? '/usr/bin/install -c' : '/usr/bin/install -c -o root -g wheel'
So, by default, gem extensions will be installed as user root of group wheel on my system. On the other hand, if RB_USER_INSTALL gets set as environment variable, gems will install with the permissions of the user calling gem install!
Ruby Code Snippet: Subsets
I needed a class/function/... to get all subsets and their complements for a given set. Welcome the (quick and dirty) class Subsets! (Idea)
irb(main):001:0> require 'subsets'
=> true
irb(main):002:0> Subsets.generate([1,2])
=> [[[], [1, 2]], [[1], [2]], [[2], [1]], [[1, 2], []]]
irb(main):003:0> Subsets.generate([1,2]).each do |s,c|
irb(main):004:1* puts "subset #{s.inspect} complement #{c.inspect}"
irb(main):005:1> end
subset [] complement [1, 2]
subset [1] complement [2]
subset [2] complement [1]
subset [1, 2] complement []
=> [[[], [1, 2]], [[1], [2]], [[2], [1]], [[1, 2], []]]
irb(main):006:0>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 class Subsets private_class_method :new # Generates all subsets and their complements def Subsets.generate(set) # :yields: subset, complement n = set.size mask = Array.new(n, false) if block_given? yield([], set) else ret = [[[], set]] end while( Subsets.next_mask(mask,n) ) do subset, complement = Subsets.generate_subset(mask,n,set) if block_given? yield( subset, complement ) else ret << [subset, complement] end end return ret if not block_given? end private def Subsets.next_mask(mask,n) i = 0 while (i < n and mask[i]) mask[i] = false i += 1 end if i < n mask[i] = true; return true end return false end def Subsets.generate_subset(mask,n,set) subset = [] complement = [] for i in 0..n-1 if mask[i] subset << set[i] else complement << set[i] end end return subset, complement end end