RB_USER_INSTALL to the rescue

Posted by Robert Gogolok Sat, 10 Oct 2009 01:23:00 GMT

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

Posted by Robert Gogolok Thu, 08 Nov 2007 02:06:00 GMT

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