|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hello!
QUESTION: Is there any way to attach a listener that will fires when the interpreter encounters an unknown Class and going to raise the NameError? For some reason all my classes are arranged the same way as files are (i.e. A::B::C <=> A/B/C.rb, one to one) So, theoretically i don't really need any usage of the 'require' keyword. My proposal is: When the interpreter encounters unknown Class it raises the 'NameError'. I'm wondering is there any way to attach a listener right before it happens (like method_missing)? Another way: begin ... rescue NameError # load needed class end But, it's not a solution, because in this case we loose the Point of execution. Thanks! ![]() -- Posted via http://www.ruby-forum.com/. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Alexey Petrushin wrote:
> Hello! > > My proposal is: > When the interpreter encounters unknown Class it raises the 'NameError'. > I'm wondering is there any way to attach a listener right before it > happens (like method_missing)? http://www.ruby-doc.org/core/classes...e.html#M001716 -- James Britt www.happycamperstudios.com - Wicked Cool Coding www.jamesbritt.com - Playing with Better Toys www.ruby-doc.org - Ruby & Documentation www.rubystuff.com - The Ruby Store for Ruby Stuff |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
module AutoRequire
def const_missing(const) puts File.join(to_s.split(/::/), const.to_s) + ".rb" end end # In A.rb: module A extend AutoRequire end A::B # In A/B.rb: module A module B extend AutoRequire end end A::B::C gegroet, Erik V. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Thanks! It works!
![]() Implementation: GLOBAL_BINDING = binding class Module def const_missing(const) full_class_name = (self == Object or self == Module) ? const.to_s : "#{self.name}::#{const}" file = full_class_name.gsub('::', '/') if File.directory?(file) eval "module #{full_class_name} end", GLOBAL_BINDING elsif File.exist?(file+".rb") script = File.read(file+".rb") unless self == Object or self == Module script = "\ module #{self.name} #{script} end " end eval script, GLOBAL_BINDING else raise "Class not found: #{full_class_name}" end result = eval "#{full_class_name}", GLOBAL_BINDING return result if result raise "Class not found: #{full_class_name}" end end # A/B/C.rb # # class C # end # A::B::C.new Notes: - in the script for the class C, we write just C, instead of all A::B::C - there are no really A and B modules, they are generated on the fly. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Alexey Petrushin wrote:
> Thanks! It works! ![]() Hi there. That's a nice solution, I think. Thanks for sharing! There might be some drawbacks in this approach, like now you cannot require these files manually because it wouldn't create the correct module nesting, but for some applications I think your code is great. Things that you probably could improve: - There's a constant named TOPLEVEL_BINDING, you can use it instead of your own constant. - You could backup the original const_missing and call it if the const is really missing: class Module alias const_missing_orig const_missing def const_missing(const) ... else const_missing_orig(const) end end end - Also I think there might be a more elegant way to create the class from the file in the correct nesting. There might be a way to do it using some class_eval or something, but I'll have to test it. TPR. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
I'm hurry up, there are some bugs in current implementation. Do not use
it as it is. Right now i'm using it in my project, so, stable solution should be available, probably in one week .-- Posted via http://www.ruby-forum.com/. |
|
![]() |
| Outils de la discussion | |
|
|