tutorials.de Buch-Aktion 05/2012
RSS-Feed anzeigen

Code that sings

URI-Handling mit Ruby

Bewerten
von Matthias Reitinger am 06.03.09 um 00:22 (1669 Hits)
Relativ absolut
ZodiacXP hatte heute das Anliegen, relative URIs in absolute umzuwandeln. Gumbo lieferte wie immer prompt einen hilfreichen Hinweis: ein entsprechender Algorithmus findet sich im RFC 3986. Als Rubyist muss man sich dieses Dokument aber nicht unbedingt zu Gemüte führen, da die Standard-Bibliothek für den Umgang mit URIs passende Klassen bereitstellt.

Das Modul URI
Nachdem man die Bibliothek mit require 'uri' eingebunden hat, kann man auch schon auf das Modul URI zugreifen (in den Beispielen werde ich diese Zeile allerdings weglassen). Module kann man in Ruby als eine Art Namensraum mit Extras verstehen (man kann sie beispielsweise als Mixins verwenden - dazu vielleicht später mal mehr in diesem Blog). Die zwei wichtigsten Methoden möchte ich kurz vorstellen:

URI.parse(uri)
Diese Methode interpretiert den übergebenen String als URI und gibt im Erfolgsfall eine Instanz der Klasse URI::Generic oder einer ihrer spezialisierten Unterklassen zurück. Beispiele für die Unterklassen wären URI::HTTP und URI::FTP für HTTP- bzw. FTP-URIs. Über diese Instanz kann man dann auf die eigenen Bestandteile der URI zugreifen, wie in folgendem...

Beispiel
Code ruby:
1
2
3
4
5
6
7
uri = URI.parse("http://www.tutorials.de/blog/code-that-sings-3117/")
puts uri.class # => URI::HTTP
puts uri.scheme # => http
puts uri.host # => [url]www.tutorials.de[/url]
puts uri.port # => 80
puts uri.path # => [url]http://www.tutorials.de/blog/code-that-sings-3117/[/url]
puts uri.fragment # => nil
Auffällig daran: uri.port stand nicht in der URI, wurde aber anhand des Schemas hergeleitet (80 ist der Standard-Port für das HTTP-Protokoll). Nicht vorhandene Teile (hier uri.fragment) liefern nil zurück.

URI.join(*str)
Ein kleines Beispiel sagt mehr als tausend Worte:

Beispiel
Code ruby:
1
2
3
4
5
6
7
8
9
10
11
12
puts URI.join("http://www.tutorials.de/", "blog/")
# => [url]http://www.tutorials.de/blog/[/url]
puts URI.join("http://www.tutorials.de/", "blog/", "code-that-sings-3117/")
# => [url]http://www.tutorials.de/blog/code-that-sings-3117/[/url]
puts URI.join("http://www.tutorials.de/blog/code-that-sings-3117/", "/forum/")
# => [url]http://www.tutorials.de/forum/[/url]
puts URI.join("http://www.tutorials.de/forum/", "programming/")
# => [url]http://www.tutorials.de/forum/programming/[/url]
puts URI.join("http://www.tutorials.de/forum/programming/", "../cgi-perl-python-ruby/")
# => [url]http://www.tutorials.de/forum/cgi-perl-python-ruby/[/url]
puts URI.join("http://www.tutorials.de/forum/", "http://www.ruby-lang.org/")
# => [url]http://www.ruby-lang.org/[/url]
Diese Methode kann also dazu verwendet werden, relative Pfadangaben in absolute URIs umzusetzen (also genau das was ZodiacXP erreichen wollte).

Instanzmethoden
Die URI-Klassen besitzen einige Instanzmethoden. Auch diese will ich ohne lange Erklärung beispielhaft vorführen:

Beispiel
Code ruby:
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
uri = URI.parse("http://www.tutorials.de/blog/code-that-sings-3117/")
 
# URI komponentenweise verändern
uri.query = "foo=bar"
uri.fragment = "top"
puts uri
# => [url]http://www.tutorials.de/blog/code-that-sings-3117/?foo=bar#top[/url]
 
# URI erweitern (wie URI.join)
puts uri.merge("uri-handling-mit-ruby-983/")
# => [url]http://www.tutorials.de/blog/code-that-sings-3117/uri-handling-mit-ruby-983/[/url]
puts uri + "uri-handling-mit-ruby-983/"
# => [url]http://www.tutorials.de/blog/code-that-sings-3117/uri-handling-mit-ruby-983/[/url]
puts uri + "http://www.ruby-lang.org/"
# => [url]http://www.ruby-lang.org/[/url]
 
puts uri.absolute? # => true
puts uri.relative? # => false
 
puts uri.route_from("http://www.tutorials.de/")
# => blog/code-that-sings-3117/?foo=bar#top
puts uri.route_from("http://www.tutorials.de/forum/")
# => ../blog/code-that-sings-3117/?foo=bar#top
puts uri.route_to("http://www.tutorials.de/blog/code-that-sings-3117/uri-handling-mit-ruby-983/")
# => uri-handling-mit-ruby-983/

Umwandlung von relativen in absolute URIs
Abschließend zu dieser kleinen Übersicht möchte ich der Vollständigkeit halber noch die Ruby-Lösung zu ZodiacXPs Problem vorstellen:
Code ruby:
1
2
3
4
5
6
7
8
9
require 'uri'
 
base = URI.parse("http://www.foo.bar/path/file.ext")
paths = ["/folder/th.ing", "this/that.foo", "http://some.where/else"]
 
paths.map! {|path| (base + path).to_s}
 
p paths
# => ["http://www.foo.bar/folder/th.ing", "http://www.foo.bar/path/this/that.foo", "http://some.where/else"]
Was es mit map! auf sich hat, wisst ihr ja schon aus dem Artikel Arbeiten auf Arrays mit Blockparametern.

- Matthias

"URI-Handling mit Ruby" bei Twitter speichern "URI-Handling mit Ruby" bei Facebook speichern

Aktualisiert: 12.07.09 um 01:27 von Matthias Reitinger

Stichworte: api, ruby, uri
Kategorien
Programming

Kommentare