ACHTUNG. Das ist ein Archiv des alten forum.ruby-portal.de. Die aktuelle Mailingliste gibt es auf lists.ruby-lang.org/pipermail/ruby-de.

NOTICE. This is a ready-only copy of the old forum.ruby-portal.de. You can find the current mailing list at lists.ruby-lang.org/pipermail/ruby-de.

Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 02 Mär 2010, 18:19 
Offline
Lehrling

Registriert: 27 Mai 2008, 14:26
Beiträge: 64
Hi,

beim Rumbasteln an FakeFS habe ich festgestellt, dass Kernel#autoload ein selbstdefiniertes Kernel#require ignoriert.


1
2
3
4
5
6
7
8
9
10
11
module Kernel
def require fn
puts fn
end
end

module Foo
autoload :Bar, "foo/bar"
end

Foo::Bar

FakeFS ist eine Gem, das das Dateisystem mockt, indem es sämtliche Methoden, die aufs Dateisystem zugreifen, überschreibt (faket). Kernel#require wird noch nicht gefaket, daran arbeite ich gerade, was auch schon recht gut funktioniert.

Aktuell bastle ich daran, dass beim Aufruf von #require erkannt wird, ob ein Teil eines Gems geladen werden soll, und FakeFS dann umgangen wird. Ich habe eigentlich damit gerechnet, dass ich damit auch #autoload-Kram abfangen kann.

Hat jemand Ideen?

Liebe Grüße,
Lars

_________________
http://github.com/lgierth


Nach oben
 Profil  
 
BeitragVerfasst: 02 Mär 2010, 19:13 
Offline
Interpreter
Benutzeravatar

Registriert: 03 Jul 2006, 14:53
Beiträge: 4872
Wohnort: RLP
Bist du dir sicher, dass autoload required und nicht "load"et? Den zusätzlichen Schritt von require (schauen, ob die Datei schon mal eingebunden wurde, bevor es load verwendet) kann sich autoload ja sparen, da die Funktion von autoload ja grob ist "wenn die Konstante fehlt, lade die angehängte datei".

Gruß,
Skade


Nach oben
 Profil  
 
BeitragVerfasst: 02 Mär 2010, 19:36 
Offline
Lehrling

Registriert: 27 Mai 2008, 14:26
Beiträge: 64
Die Kernel-Doku redet da explizit von #require, ich habs aber auch mit #load getestet.

_________________
http://github.com/lgierth


Nach oben
 Profil  
 
BeitragVerfasst: 08 Mär 2010, 12:27 
Offline
Lehrling

Registriert: 27 Mai 2008, 14:26
Beiträge: 64
Ich hab jetzt auch mal auf ruby-forum.com nachgefragt: ruby-forum.com/topic/205612

Mir ist auch noch aufgefallen, dass die Doku zu Kernel#autoload ansich bereits widersprüchlich ist, da wird von Kernel::require geredet, obwohl es nur #require gibt. ::require tut jedenfalls auch nicht ;)

_________________
http://github.com/lgierth


Nach oben
 Profil  
 
BeitragVerfasst: 08 Mär 2010, 15:23 
Offline
Lehrling

Registriert: 27 Mai 2008, 14:26
Beiträge: 64
So, ich wurde gerade auf eine Diskussion auf ruby-core verwiesen, die sich um genau das Thema dreht, aber irgendwann eingeschlafen ist.

Jedenfalls nutzt #autoload gar nicht erst das Userland-#require, sondern geht direkt über rb_require() im C-Code. Ich werde dann die Tage mal probieren, das Problem über Object#const_missing zu lösen.

_________________
http://github.com/lgierth


Nach oben
 Profil  
 
BeitragVerfasst: 15 Mär 2010, 13:43 
Offline
Lehrling

Registriert: 27 Mai 2008, 14:26
Beiträge: 64
So,

ich bin jetzt den Weg über #const_missing gegangen, klappt prima.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    module Autoload
def fakefs_autoload const, file
Require.autoloadable[self] ||= {}
Require.autoloadable[self][const] = file
end

def fakefs_autoload? const
hsh = Require.autoloadable[self]
return hsh[const] if hsh
end

def fakefs_const_missing name
Require.autoloaded[self] ||= {}
file = autoload? name
if file and !Require.autoloaded[self][name]
Require.autoloaded[self][name] = true
require file
return const_get name if const_defined? name
end
parent = (self == Object) ? "" : self.to_s + "::"
raise NameError, "uninitialized constant #{parent}" + name.to_s, caller
end
end




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
  def test_fakes_autoload
FakeFS::Require.activate! :autoload => true

code = <<-EOS
module FakeFSTestAutoload
autoload :Foo, "fake_fs_test_autoload/foo"
autoload :Bar, "fake_fs_test_autoload/bar"
end

EOS

File.open "fake_fs_test_autoload.rb", "w" do |f|
f.write code
end
code = <<-EOS
module FakeFSTestAutoload
module Foo
end
end

EOS

File.open "fake_fs_test_autoload/foo.rb", "w" do |f|
f.write code
end

require "fake_fs_test_autoload"

# autoload
assert FakeFSTestAutoload::Foo

# autoload with non-existing path
assert_raise LoadError do
FakeFSTestAutoload::Bar
end

# no autoload
assert_raise NameError do
FakeFSTestAutoload::Baz
end

FakeFS::Require.deactivate!
FakeFS::Require.clear
end

_________________
http://github.com/lgierth


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach: