main
Ruby is a language designed in the following steps:
(Yukihiro Matsumoto, Mon, 13 Feb 2006 13:43:02 +0900)
Warum Ruby noch nicht das Ende jeder Entwicklung ist:
Aber…
Ruby ist angekommen:
TIOBE-Index: Mißt Verfügbarkeit von Programmierern, Kursen, Diensten
Top-Ten:
Ruby makes me happy because it allows me to write beautiful code.
Aesthetics are strongly linked to enjoyment. It’s not just about “getting the job done”. It’s also about being satisfied with the way the job is getting done — being motivated to improve the way the job is getting done, and to take pride in its execution.
I simply can’t do that with ugly code. Ruby allows me to escape the ugliness. Thus, Ruby allows me to be happy about programming. Happiness leads to motivation. Motivation leads to productivity.
—David Heinemeier Hansson (creator of Rails)
Ruby’s the only language I’ve ever used that feels like it was designed by a programmer, and not
—William Morgan
variable methode
Konstante Klassenname
@instanzvariablen
false true
nil
"string" 'string'
:symbol
[1, :two, "three"]
{:action => "edit", :id => 3}
/[A-Za-z][_a-z0-9]*/
"Carsten".length –1962.abs
user = User.new
user.vorname = "Carsten"
user.vorname.length
user = User.new("Carsten")
cart.add_line_item(purchase)
class User < Human
attr_reader :vorname
def initialize(vorname)
@vorname = vorname
end
def say_goodnight(niceness = "Dear")
print "Good night, #{niceness} #{@vorname}!"
end
end
Ein Ruby-Programm ist eine Folge von Ausdrücken
Ausdrücke kann man interaktiv auswerten
(autoload 'ruby-mode "ruby-mode" "Ruby editing mode." t)
(add-to-list 'auto-mode-alist '("\.r\\(b\\¦ake\\)$" . ruby-mode))
(add-to-list 'auto-mode-alist '("[Rr]akefile\\'" . ruby-mode))
(add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode))
(add-hook 'ruby-mode-hook
'(lambda () (ruby-electric-mode)))
(autoload 'ruby-electric-mode "ruby-electric" "Ruby electric editing mode." t)
(autoload 'run-ruby "inf-ruby" "Run an inferior Ruby process")
(autoload 'inf-ruby-keys "inf-ruby"
"Set local key defs for inf-ruby in ruby-mode")
(add-hook 'ruby-mode-hook
'(lambda ()
(inf-ruby-keys)))
(setq ruby-program-name "irb --inf-ruby-mode -f")
Ruby-Mode: Wie erwartet
Ruby-Electric-Mode: Erspart etwas Tipp-Arbeit
Inferior-Ruby-Mode:
5
a = 1
b = 2; nil
Programm = Folge von Ausdrücken
d = 4 + 5 +
6 + 7
e = 8 + 9 \
+ 10
Zeilenende beendet Ausdruck, es sei denn
=begin rdoc
Kaufe eine Cola mit Euros
=end
def buy_coke # parameterlos
...
Kommentare:
#
bis zum Zeilenende=begin
und =end
am Anfang der Zeileclass User
def initialize(x)
@vorname = x
end
def vorname
@vorname
end
def vorname=(x)
@vorname = x
end
end
Der Inhalt von Objekten ist nur über Methoden erreichbar
Instanzvariablen
sichtbar zu machen, müssen Methoden definiert werden:
obj.meth
zum Lesen („getter“)obj.meth=
zum Schreiben („setter“)
=
gehört zum Methodennamen!obj.meth = x
ist Abkürzung für obj.meth=(x)
Abkürzung: Attribute (Instanzvariable + gleichnamige Methode(n))
class User
def initialize(x)
@vorname = x
end
# Schreibbares Attribut (true)
attr :vorname, true
# Alternative Schreibweise:
attr_accessor :vorname
end
Ruby definiert Klassenmethoden, um setter-/getter-Methoden automatisch zu definieren:
class Name |
attr attribute [, writable ] |
attr_reader attribute [, attribute ]... |
attr_writer attribute [, attribute ]... |
attr_accessor attribute [, attribute ]... |
end |
123456 → 123456
0d123456 → 123456
123_456 → 123456
–543 → –543
0xaabb → 43707
0377 → 255
–0b10_1010 → –42
123_456_789_123_456_789
→ 123456789123456789
Numerische Typen:
?a → 97
?\n → 10
?\C-a → 1
(Ruby 1.8:) Einzelne Zeichen sind auch nur Ganzzahlen:
Viele Operationen werden wie Methoden aufgerufen:
–1.3.abs → 1.3 |
53.to_s → “53” |
–1.3.zero? → false |
53.to_s(16) → “35” |
?a.chr → “a” |
|
97.chr → “a” |
Manche Methoden haben Blöcke:
3.times { puts "Hurra!" }
3.times do
puts "Hurra!"
end
12.34 → 12.34
–0.1234e2 → –12.34
1234e–2 → 12.34
Numerische Typen (Fortsetzung):
In der Standardbibliothek gibt es noch
require 'bigdecimal'
require 'bigdecimal/math'
include BigMath
BigMath::PI(200)
→ #<BigDecimal:481e8,’0.3141592653 5897932384 6264338327 9502884197 1693993751 0582097494 4592307816 4062862089 9862803482 5342117067 9821480865 1328230664 7093844609 5505822317 2535940812 8481117450 2841027019 3852110555 9644622948 9549303819 6442881097 5665930147 8208315213 4043E1’,240(576)>
Operationen auf Zahlen wie in C:
Exponentiation | ** |
2**74 → 18889465931478580854784 |
Unäre Operationen | ~ + – |
~1 → –2; +1 → 1; –1 → –1 |
Mul/Div/modulo | * / |
2*2.0 → 4.0; 5/3 → 1; |
5/3.3 → 1.5152; 3.05%1.5 → 0.0499 |
||
Plus/Minus | + – |
1+1 → 2; 1.3–3 → –1.7 |
Shift | << >> |
2<<12 → 8192; 4711>>2 → 1177 |
Bitweises Und | x%x |
4711&4712 → 4704 |
Bitweises Oder | ¦ ^ |
4711¦4712 → 4719; 4711^0x200 → 4199 |
Infix-Operatoren sind Abkürzung für Methodenaufrufe:
a = 1
a + 1 → 2
a.+(1) → 2
1 + 1 → 2
1.+(1) → 2
Unäre Operatoren + und – heißen zur Unterscheidung anders:
(Leere Klammern kann man weglassen, allerdings hat der Parser von irb in diesem Fall Probleme damit.)
a = 1
–a → –1
a.–@() → –1
a.–@ → –1
== 《!=》 | gleicher Wert |
=== |
“passt zu” (unsymmetrisch!) |
<=> |
< (–1), == (0), oder > (+1)? |
< , <= , > , >= |
meist definiert auf <=> |
=~ 《!~》 | RE-Match |
eql? |
gleicher Wert ohne Konvertierung |
equal? |
identisch |
!=
ist Negation von ==
, !
ist Negation von =
class MyWidget
attr_reader :str
def <=>(other)
str <=> other.str
end
include Comparable
end
<=>
zu definieren:Comparable
definiert darauf <
, <=
, >
, >=
, und between?
module Comparable
def ==(other)
self.object_id == other.object_id ¦¦ (self <=> other) == 0
end
def >(other); (self <=> other) > 0; end
def >=(other); (self <=> other) >= 0; end
def <(other); (self <=> other) < 0; end
def <=(other); (self <=> other) <= 0; end
def between?(min, max)
(min <= self) && (self <= max)
end
end
Comparable
ist ein Mixin: Ein Modul, dessen Konstanten und Methoden mit include
Bestandteil der inkludierenden Klasse werden.
>> for a in 1..3
>> puts a
>> end
1
2
3
→ 1..3
>> for a in 1...3
>> puts a
>> end
1
2
→ 1...3
Anfang und Ende eines Bereiches in einem Datentyp
a..b |
entspricht mathematisch | [a, b] |
a...b |
entspricht mathematisch | [a, b[ |
(1..3).class
→ Range
Operator ===
prüft, ob der Operand zum Objekt paßt:
(0...18) === –1 |
→ false |
(0...18) === 0 |
→ true |
(0...18) === 17 |
→ true |
(0...18) === 18 |
→ false |
(0..18) === –1 |
→ false |
(0..18) === 0 |
→ true |
(0..18) === 17 |
→ true |
(0..18) === 18 |
→ true |
(0..18) === 19 |
→ false |
Folgende Klassen haben jeweils genau eine (nicht mutierbare) Instanz:
In Abfragen sind false
und nil
falsch, alles andere wahr!
TRUE = true
class TrueClass
def to_s; "true"; end
def ¦(x); true; end
def &(x)
(x.nil? or x == false) ? false : true
end
def ^(x)
(x.nil? or x == false) ? true : false
end
end
FALSE = false
class FalseClass
def to_s; "false"; end
def &(x); false; end
def ¦(x)
(x == false
or x.nil?) ? false : true
end
alias :^ :¦
end
Zeichenketten sind wichtiger Grundtyp (im Gegensatz zu Zeichen!)
Basis: Folge von 8-bit-Bytes
Literale sind entweder einfachquotiert (nur \’ und \\)...
'hello' → hello |
'a backslash \'\\\'' → a backslash ’\’ |
%q/simple string/ → simple string |
%q(nesting (really) works) → nesting (really) works |
%q no_blanks_here → no_blanks_here |
oder doppelquotiert (sei a = 123
):
"\123mile" → Smile |
"Say \"Hello\"" → Say “Hello” |
%Q!"I said 'nuts'," I said! → “I said ‘nuts’,” I said |
%Q["I said 'nuts'," I said] → “I said ‘nuts’,” I said |
%["I said 'nuts'," I said] → “I said ‘nuts’,” I said |
"Try #{a + 1}, not #{a – 1}" → Try 124, not 122 |
Q{Try #{a + 1}, not #{a – 1}} → Try 124, not 122 |
→ Try 124, not 122 |
%{...#{ a = 1; b = 2; a + b }...} → ...3… |
HERE-Dokumente:
a1:
Double quoted here document.
It is Sun Jan 21 20:16:03 +0100 2007
a2:
This is single quoted.
The above used #{Time.now}
a1 = <<HERE
Double quoted \
here document.
It is #{Time.now}
HERE
a2 = <<–'THERE'
This is single quoted.
The above used #{Time.now}
THERE
Konkatenation: 'and "a\123" = ' "a\123"
→ and “a\123” = “aS”
Ruby 1.9:
?a |
→ “a” |
"a"[0] |
→ “a” |
"a"[1] |
→ nil |
"ü"[0] |
→ “ü” |
"ü"[1] |
→ nil |
"a".length |
→ 1 |
"ü".length |
→ 1 |
"水".length |
→ 1 |
"a".encoding |
→ #<Encoding:UTF-8> |
Ruby 1.8:
?a |
→ 97 |
"a"[0] |
→ 97 |
"a"[1] |
→ nil |
"ü"[0] |
→ 195 |
"ü"[1] |
→ 188 |
"ü"[2] |
→ nil |
"a".length |
→ 1 |
"ü".length |
→ 2 |
"水".length |
→ 3 |
1.8: UTF-8 scheint durch
s = "Müller"; s[2] = 164; s[4] = ?z; puts s |
☞ Mälzer |
1.9: Strings sind Zwitter von Zeichenketten und Bytefolgen
"abcü水".bytes.to_a |
→ [97, 98, 99, 195, 188, 230, 176, 180] |
"abcü水".codepoints.to_a |
→ [97, 98, 99, 252, 27700] |
"a".ord |
→ 97 |
"水".ord |
→ 27700 |
97.chr |
→ “a” |
27700.chr("UTF-8") |
→ “水” |
Mutieren:
s = "Hello"
s << " "
s << "world"
s[1] = "aa"
#s[7..11] = "Welt"
s[7..-1] = "Welt"
Operationen auf Strings
"a" + "b" |
→ “ab” |
"a" + 1 |
☠ |
"a" + 1.to_s |
→ “a1” |
"a#{1}" |
→ “a1” |
"ab" * 3 |
→ “ababab” |
"a%sb" % 3 |
→ “a3b” |
"a%sb%d" % ["x", 2] |
→ “axb2” |
Symbole sind spezielle konstante Strings:
Interpolation (sei a = “cat”):
:’catsup’ → :catsup |
%s{catsup} → :catsup |
:”#{a}sup” → :catsup |
:’#{a}sup’ → :”\#{a}sup” |
%s{#{a}sup} → :”\#{a}sup” |
Schreibweise mit Doppelpunkt:
:Object |
:my_variable |
:”Ruby rules” |
people = Hash.new
people[:nickname] = 'Matz'
people[:language] = 'Japanese'
keystring = 'last name'
people[keystring.intern] = 'Matsumoto'
people[:'last name']
→ 'Matsumoto'
intern
to_s
id2name
Reguläre Ausdrücke dienen zum Vergleichen und Zerlegen von Strings.
/pattern/
/pattern/options
%r{pattern}
%r{pattern}options
Regexp.new( 'pattern' [ , options ] )
Reguläre Ausdrücke wissen über Unicode (UTF-8) Bescheid!
"eins zwei drei".scan(/./) |
→ [“e”, “i”, “n”, “s”, ” ”, “z”, “w”, “e”, “i”, ” ”, “d”, “r”, “e”, “i”] |
"eins zwei drei".scan(/\w+/) → [“eins”, “zwei”, “drei”] |
"Lieschen Müller, Frank Meyer".split(/,\s+/) |
→ [“Lieschen M\303\274ller”, “Frank Meyer”] |
md = 134.102.218.46 .match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ |
→ #<MatchData:0×4bdc00> |
Reguläre Ausdrücke lassen sich auch als Index benutzen:
schen
Lieschen Mueller
a = "Lieschen Müller"
puts a[/.ch\S+/]
a[/ü/] = "ue"
puts a
Arrays beginnen immer bei Index 0 und können dynamisch wachsen.
Literale:
[] |
[1, 2, 3] |
[Time.now, Process::Sys.getuid, Process.times.utime] |
→ [Sun Jan 21 21:11:30 +0100 2007, 501, 41.51] |
a = %w{The rat sat on the mat} |
→ [“The”, “rat”, “sat”, “on”, “the”, “mat”] |
a[2..–2] → [“sat”, “on”, “the”] |
a[4711] → nil |
Hashes werden mit einem beliebigen Datenobjekt indiziert. |
(Andere Namen für Hashes: Assoziative Arrays, Dictionaries.) |
Literale:
colors = { "red" => 0xf00,
"green" => 0x0f0,
"blue" => 0x00f
}
puts colors["red"].to_s(16)
Ausgabe: f00
{}
{ "red" => 0xf00, "green" => 0x0f0,
"blue" => 0x00f }
Indexe (Keys) sollten sich nicht ändern.
Spezialfall: Strings als Keys werden beim Anlegen kopiert.
Time.now
require 'date'
)ausrede = if nutzer.alter < 18
"minderjährig"
elsif nutzer.konto < 1000
"kein Geld"
else
nil
end
if nutzer.alter < 18
puts "minderjährig"
elsif nutzer.konto < 1000
puts "kein Geld"
else
auto.kaufen(nutzer)
end
Es gibt keine Anweisungen, nur Ausdrücke!
Kurzform für einfache bedingte Ausführung:
Statt:
if User.count == 0
return false
end
auch:
return false if User.count == 0
Weniger üblich:
leap = case
when year % 400 == 0
true
when year % 100 == 0
false
else
year % 4 == 0
end
Übliches case
:
===
case input
when 'q'
quit
when /w (.*)/
write($1)
else
error
end
===
auf Class
case shape
when Square, Rectangle
# ...
when Circle
# ...
when Triangle
# ...
else
# ...
end
Nützlich für den Vergleich mit ===
sind auch Ranges:
text = case age
when 0...18
"minderjährig"
when 18...21, 65..999
"Gefahrenzuschlag"
else
"Normalpreis"
end
Bedingung ist Ausdruck |
wie jeder andere: |
while line = gets
puts line
end
while begin
print "Eingabe: "
line = gets
end
puts line
end
i = 0
while i < 3
puts "Hurra"
i += 1
end
until
ist Gegenteil von while
3.times do
puts "Hurra"
end
Blöcke können Argumente haben:
(1..3).each do ¦i¦
puts "Hurra #{i}"
end
("aa".."zz").each do ¦ix¦
buchreihe[ix].anlegen
end
3.times do ¦i¦
puts "Hurra #{i+1}"
end
["Fritz", "Horst", "Ernst"].each do ¦nm¦
puts "Hallo #{nm}!"
end
class Integer
def times
i = 0
while i < self
yield i
i += 1
end
self
end
end
Wie implementiert man eine Methode, die Argumente an Blöcke übergibt?
yield
ruft den übergebenen Block auf
yield
werden Argumente des BlocksEnumerable
zusammengefaßt
each
der inkludierenden Klassefind
, select
, map
, grep
, inject
def mean(array)
array.inject(0) do ¦sum, x¦
sum += x
end / array.size.to_f
end
class Array
def mean
inject(0) do ¦sum, x¦
sum += x
end / size.to_f
end
end
def mean(array)
sum = 0
array.each do ¦i¦
sum += i
end
return sum / array.size.to_f
end
ARGV.each do ¦fn¦
if t = parse_id3(fn)
puts "#{fn}:"
t.zip(NAMES).each do ¦v, n¦
puts " #{n}: #{v}"
end
else
puts "#{fn}: No tags."
end
end
NAMES = %w(track artist album year comment genre)
FORMAT = 'Z30Z30Z30Z4Z30C'
def parse_id3(mp3_file)
open(mp3_file) do ¦f¦
f.seek(–128, File::SEEK_END)
if f.read(3) == "TAG"
return f.read(125).unpack(FORMAT)
end
end
return nil
end
#!/usr/bin/env ruby
require "rexml/document"
ARGV[0] ¦¦= "#{ENV['HOME']}/Library/EyeTV Archive"
ARGV.each do ¦di¦
puts "#{di}:"
Dir["#{di}/*/*.eyetvp"].each do ¦pf¦
d = REXML::Document.new(File.open(pf))
title = d.elements["//string[preceding-sibling::key[.='title']]"].text
du = `du -sh "#{File.dirname(pf)}"`.chomp
du["\t#{di}/"] = ' '
puts "#{du}: #{title}"
end
end
#!/usr/bin/env ruby
%w(rubygems hpricot open-uri simple-rss active_support pp).each do ¦x¦
require x
end
Dir.chdir("/Users/cabo/Movies/es")
feed = SimpleRSS.parse(open("http://www.ehrensenf.de/feed/atom/"))
links = feed.entries.map{¦x¦ x.link}
vlinks = links.map {¦li¦
doc = Hpricot(open(li + "?vid=Quicktime"))
(doc/"#videolinks a[@title]").map{¦x¦ x['href']}
}
vlinks.flatten.select{¦x¦ x != ''}.each { ¦vl¦
pp `wget -N '#{vl}'`
}
require 'gserver'
class ChatServer < GServer
def initialize(port=20606, host=GServer::DEFAULT_HOST)
@clients = []
super(port, host, Float::MAX, $stderr, true)
end
def serve(sock)
...
end
end
server = ChatServer.new(*ARGV[0..1])
server.start(–1)
server.join
def bc(m, sock=nil)
(@clients – [sock]).each { ¦c¦ c.puts m }
end
def serve(sock)
@clients << sock
hostname = sock.peeraddr[2] ¦¦ sock.peeraddr[3]
bc "#{hostname} has joined the chat.", sock
while message = sock.gets and message !~ %r(^/q)
bc "#{hostname}: #{message.chomp}", sock
end
ensure
@clients.delete(sock)
bc "#{hostname} has left the chat."
end
variable methode
Konstante Klassenname
@instanzvariablen
@@klassenvariablen
Klassennamen sind Konstanten:
Range.class
→ Class
Class.methods – Object.methods
→ [“nesting”]
x[3] |
ist eine Abkürzung für | x.[](3) |
x[3, 4, 5] |
ist eine Abkürzung für | x.[](3, 4, 5) |
x.a = 5 |
ist eine Abkürzung für | x.a=(5) |
x[3] = 5 |
ist eine Abkürzung für | x.[]=(3, 5) |
x[3, 4] = 5 |
ist eine Abkürzung für | x.[]=(3, 4, 5) |
Methodennamen können auf ! oder ? enden:
Bestimmte Operationen sind aus der Sprache definiert und können nicht als Methoden definiert werden:
!
&&
¦¦
not
or
and
? :
!=
!~
..
...
=
(s.o.!) **=
%=
/=
usw.defined?
¦¦
und &&
liefern nicht true
und false
, sondern den ersten Operanden, der ihr Ergebnis bestimmt. Das kann man auch in ¦¦=
und &&=
ausnutzen!
a = "Peter"
b = nil
a ¦¦ b
b ¦¦ a
b ¦¦= a
Variablenreferenzen und Methodenaufrufe sehen u.U. gleich aus.
x.a
puts(3)
a + 1
— Methodenaufruf oder Variablenreferenz?
def a
1
2
end
a #=> 2
def b
1
return 2
3
end
b #=> 2
Methoden-Rümpfe sind Folgen von Ausdrücken
Wie bei jeder solchen Folge:
Der letzte Ausdruck wird zurückgeliefert
Ausnahme: return
<Wert>
nil
)def a(x, y)
puts "x=#{x}, y=#{y}"
end
def b(*args)
p args
end
a(1, 2)
a 1, 2
arr = [3, 4]
a *arr
b 1, 2
b(1, 2)
b(1, 2, *arr)
b 1, 2, 4 => 5, 6 => 7
b 1, 2, 4 => 5, 6 => 7, *arr
Parameter und Argumente: mit oder ohne Klammern
Freischwebende Hash-Bestandteile am Ende:
werden zu einem Hash kombiniert
Ein Sternchen („Splat“) vor einem:
Für Zuweisungen gelten ähnliche Regeln wie bei der Parameterübergabe:
a, b = b, a |
a, b = *arr |
*arr = a, b |
Sonderfall: Ein Array auf der rechten Seite einer Mehrfachzuweisung verhält sich wie ein splat:
a, b = arr |
def a(x, y, &b)
p b.class
p b.call(x, y)
$b = b
end
a(1, 2) do ¦m, n¦
p [m, n]
"na fein"
end
$b.call(3, 4)
repeat(2) do
puts "Hello."
end
# Hello.
# Hello.
def repeat(n)
n.times { yield } if block_given?
end
def repeat(n, &block)
n.times { block.call } if block
end
def repeat(n, &block)
n.times { yield } if block
end
class A
attr_accessor :name
def initialize(name)
@name = name
end
def to_s
@name
end
end
a = A.new("fritz")
def a.normalize!
@name.capitalize!
end
a.normalize!
Methoden können nicht nur für ganze Klassen definiert werden, sondern auch für einzelne Objekte:
class << a
def normalize!
@name.capitalize!
end
end
class Regexp
def Regexp.is_valid?(str)
begin
compile(str)
valid = true
rescue RegexpError
valid = false
end
end
end
Regexp.is_valid? "Spitze!" |
→ true |
Regexp.is_valid? "Spitze)" |
→ false |
Class
und Module
geerbt (deren Instanzmethoden!)class A; end
~ A = Class.new
class Module
def <; ...superklasse?... end
def ===; ...instanz von?... end
def ancestors; ... end
def attr; ... end
def include; ... end
end
class Class
include Module
def new; ... end
def superclass; ... end
end
require 'rubygems'
require 'action_mailer'
class SimpleMailer < ActionMailer::Base
def simple_message(recipient)
from 'leonardr@example.org'
recipients recipient
subject 'A single-part message for you'
body 'This message has a plain text body.'
end
end
make: Makefile ist eine DSL
Warum nicht das gleiche in Ruby? ➔ Rakefile
task :default => [:build, :test]
task :build => ["hello", "doc.pdf"]
SRC = FileList["*.c"]
OBJ = SRC.ext("o")
desc "Build hello out of the object files"
file "hello" => OBJ do
sh "cc -o hello #{OBJ}"
end
file "main.o" => "header.h"
task :test do
ruby "test/unittest.rb"
end
rule '.o' => '.c' do ¦t¦
sh "cc -c -o #{t.name} #{t.source}"
end
task "doc.pdf" do
# ...
end
gem list --remote
gem install rails
gem update
BlueCloth (1.0.0) | junebug-wiki (0.0.27) | rcodetools (0.4.1.0) |
builder (2.0.0) | libxml-ruby (0.3.8.4) | RedCloth (3.0.4) |
camping (1.5.180) | libxslt-ruby (0.3.6) | rmagick (1.14.1) |
capistrano (1.3.1) | markaby (0.5) | rmail (0.17) |
cgi_multipart_eof_fix (2.0.2) | memcache-client (1.2.0) | rspec (0.7.5.1) |
cheat (1.2.1) | memcache-client-stats (1.1.0) | ruby-prof (0.4.1) |
daemons (1.0.4) | metaid (1.0) | ruby2ruby (1.1.4) |
diff-lcs (1.1.2) | mime-types (1.15) | rubyforge (0.4.0) |
dr_nic_magic_models (0.8.1) | mofo (0.1.1) | rubygems-update (0.9.1) |
emp (1.0.0) | mongrel (0.3.14) | RubyInline (3.6.2) |
erubis (2.1.0) | ncurses (0.9.1) | rubyscript2exe (0.5.1) |
facets (1.7.46) | needle (1.3.0) | simple-rss (1.1) |
fastri (0.2.1.1) | net-sftp (1.1.0) | sources (0.0.1) |
fastthread (0.6.2) | net-ssh (1.0.10) | sqlite3-ruby (1.2.0) |
ferret (0.10.14) | ParseTree (1.6.4) | tar2rubyscript (0.4.8) |
gem_plugin (0.2.2) | radiant (0.5.2) | teius (0.12) |
heckle (1.2.0) | radius (0.5.1) | wirble (0.1.2) |
hoe (1.1.7) | rails (1.2.1) | xhtmldiff (1.0.0) |
hpricot (0.4.92) | railsbench (0.9.1) | xml-simple (1.0.10) |
image_science (1.1.0) | rake (0.7.1) | ZenTest (3.4.3) |
Ruby:
require
require 'rubygems'
und require
/gem
Gems für Systemadministration und Deployment:
capistrano
/vlad
, deprec
/carpet
puppet
(facter
), chef
(ohai
), sprinkle
package :ruby do
description 'Ruby Virtual Machine'
version '1.8.6'
source "ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-#{version}-p111.tar.gz"
requires :ruby_dependencies
verify do
has_file '/usr/bin/ruby'
end
end
package :ruby_dependencies do
description 'Ruby Virtual Machine Build Dependencies'
apt %w( bison zlib1g-dev libssl-dev libreadline5-dev libncurses5-dev file )
end
god
integrity
journeta
, nanite