# Idioms for separating out OS-specific stuff

**URL:** <https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715>\
**Category:** Ruby\
**Created:** [March 8, 2006, 10:18pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715 "2006-03-08T22:18:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 10:18pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/1 "2006-03-08T22:18:41Z")

</div>

I have a few functions that:

- get the current user’s login name
- checks to see what the CPU % of a process is (non the Ruby  
process, another process). This includes all the threads that the  
process has
- forks a new process
- sees if a process is still running
- gets the utilization percentage of a NIC on the machine
- the load average of the machine
- the number of CPUs on a given machine

This is all working fine on Linux with kernel 2.4. However, the code  
doesn’t quite run correctly on a 2.6 kernel (not sure why yet). And  
forget about OS X and Windows and \*BSD.

Are there any good Ruby idioms for managing the separate OS-specific  
functions?

My first thought:  
module SystemSpecificMethods  
module Linux  
# generic linux functions in here

```
module 2.4
  # linux 2.4 functions in here
end

module 2.6
  # linux 2.6 functions in here
end

```

end

module Windows  
# Windows functions here  
end

module BSD  
# OS X and maybe \*BSD functions here  
end  
end

And then probe (somwhow?) to figure out what OS I’m running on and  
then including the correct modules into my code. So, if I were using  
Linux 2.6, I’d include SystemSpecificFunctions::Linux and  
SystemSpecificFunctions::Linux::2.6.

But I’m sure that’s a pretty dumb way of doing it, as I’m not terribly  
bright.

Joe

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 10:46pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/2 "2006-03-08T22:46:25Z")

</div>

On Mar 8, 2006, at 4:18 PM, Joe Van D. wrote:

> And then probe (somwhow?) to figure out what OS I’m running on and  
> then including the correct modules into my code.

As far as probing goes…

irb(main):026:0\> Config::CONFIG[‘host\_os’]  
=\> “darwin8.4.0”  
irb(main):027:0\> Config::CONFIG[‘arch’]  
=\> “powerpc-darwin8.4.0”

etc.

You can also try shelling out and calling uname, but that of course  
won’t work on windows for example.

logan:/Users/logan% uname -s  
Darwin  
logan:/Users/logan% uname -r  
8.5.0  
logan:/Users/logan% uname -v  
Darwin Kernel Version 8.5.0: Sun Jan 22 10:38:46 PST 2006;  
root:xnu-792.6.61.obj~1/RELEASE\_PPC  
logan:/Users/logan% uname -a  
Darwin logan-capaldos.poly.edu 8.5.0 Darwin Kernel Version 8.5.0: Sun  
Jan 22 10:38:46 PST 2006; root:xnu-792.6.61.obj~1/RELEASE\_PPC Power  
Macintosh powerpc

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 10:52pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/3 "2006-03-08T22:52:35Z")

</div>

On Mar 8, 2006, at 4:18 PM, Joe Van D. wrote:

> Are there any good Ruby idioms for managing the separate OS-  
> specific functions?

Lots of ways to do this. Here is another thought:

class A  
case RUBY\_PLATFORM  
when /linux/  
def alpha; ‘linux implmentation’; end  
when /darwin/  
def alpha; ‘darwin implementation’; end  
else  
def alpha; ‘default implementation’; end  
end  
def beta; ‘works on all systems’; end  
end

puts A.new.alpha # ‘darwin implementation’ (on Mac OS X)  
puts A.new.beta # ‘works on all systems’

Gary W.

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 11:01pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/4 "2006-03-08T23:01:53Z")

</div>

Joe Van D. wrote:  
…

> - gets the utilization percentage of a NIC on the machine  
> …

I’ve been wondering how to do that, either on 2.4 or 2.6. What are you  
using?

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 11:08pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/5 "2006-03-08T23:08:03Z")

</div>

On 3/8/06, Joel VanderWerf [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Joe Van D. wrote:  
> …
> 
> > - gets the utilization percentage of a NIC on the machine  
> > …
> 
> I’ve been wondering how to do that, either on 2.4 or 2.6. What are you  
> using?

I don’t have the code in front of me, but there’s a file in /proc  
(maybe /proc/net?) that details the TX and RX information for each NIC  
(in packets or bytes transferred). Keep track of the total amount of  
stuff transferred over time, divide by the capacity of the NIC over  
that time period (I think I cheat and assume gigabit NICs, since  
that’s all we have here), and there you are.

It turns out that it’s pretty hard to get the utilization much above  
10%. But I’m not sure of the best way of generating a ton of useless  
network traffic.

Joe

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [March 8, 2006, 11:56pm UTC](https://www.ruby-forum.com/t/idioms-for-separating-out-os-specific-stuff/78715/6 "2006-03-08T23:56:51Z")

</div>

Quoting Joe Van D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> - the number of CPUs on a given machine  
> …

> And then probe (somwhow?) to figure out what OS I’m running on  
> and  
> then including the correct modules into my code. So, if I were  
> using  
> Linux 2.6, I’d include SystemSpecificFunctions::Linux and  
> SystemSpecificFunctions::Linux::2.6.

Maybe it would be better to break up the modules by feature rather  
than platform. Forking processes is the same on BSD and all Linux  
flavors, for example.

So, you’d have a module for POSIX-style fork, for example, and  
another for /proc/cpuinfo. The former would provide just the  
process creation methods, and the latter would provide just the  
methods for enumerating CPUs.

Then you could give each module a singleton method to test for the  
presence of its associated feature – e.g. check whether  
‘/proc/cpuinfo’ exists.

Then you could iterate through those modules and simply include the  
ones whose feature checks pass. Probably you’d want to write some  
additional stuff to wrap that process too.

Anyway, advantages:

- automatically deal with unknown systems that have combinations of  
known features

- avoid duplication between different platforms with common  
features

-mental
