Eleanor McHugh, a physicist by training, will be talking about how to make *nix systems work naturally within the Ruby environment.
The Unix Way
Eleanor actually hates Unix, but recognizes that it’s a very effective operating system for getting things done. It’s DRY: build little things, build them well, don’t build them twice. There’s a natural marriage between agile Ruby and the Unix philosophy.
Unix provides basic services which make it a very useful OS to “muck about with”:
- virtual memory
- process management
- hierarchical file system
- user permissions
- interprocess communication
Ruby provides some “really lovely” utilities:
- Kernel.system
- Kernel.spawn
- IO.popen
- Open3.popen3
However, if you’re doing a lot of IO, you end up doing a lot of select()
s and keeping a lot of file descriptors open.
System Calls with Ruby DL
DL, which Ruby delivers out of the box, is a way to wrap a C library with a Ruby call. This is a nice way to access the underlying kernel system calls without relying on the Ruby IO implementations.
This is superior to Ruby’s syscall
, in that you can actually get results back from the function call.
Using mmap
allows you to do much faster memory reads, rather than do slower file reads.
Using kqueue
/epoll
/inotify
allows you to build evented ruby (like EventMachine, but without EventMachine).
Using pipes allows you to build efficient IPC.
The drawback is that using DL means more verbose code, and more error prone code. (Pointer math FTL!) So, for things like sockets, use the Ruby API unless you specifically need kernel-level eventing.
Multicore
The lack of real thread support in Ruby can be addressed by using multiple processes, held together with IPC (sockets, pipes, memory mapped files). This is the traditional “Unix way” for handling multiple processes.
About the Author