2011-07-17 49 views
2

這可能聽起來很混亂,但我正在和一小羣新人一起工作,我試圖用紅寶石抽象出一些東西,以使事情更順利。我遇到問題的部分是命名空間。如何在動態生成的模塊中運行Proc?

基本上,可以創建與紅寶石名字空間:

module EIF 
    module Core 
    module Entities 
    #stuff 
    end 
    end 
end 

module EIF 
end 

module EIF::Core 
end 

module EIF::Core::Entities 
#some stuff 
end 

的是,這是誠實繁瑣。我想要類似於C#的東西,您只需將名稱空間定義爲:

namespace EIF.Core.Entities 
{ 
    #Some stuff 
} 

並且完成它。我設法通過使用eval創建模塊類似的東西(名稱匹配正則表達式後)

def namespace(path) 
    if path.match(/^([A-Z][a-zA-Z0-9]*)(::[A-Z][a-zA-Z0-9_]*)*$/) 
    spaces = path.split("::") 
    code = "" 
    spaces.each { |m| code << "module #{m}\n" } 
    spaces.each { code << "end\n" } 
    eval(code) 
    else 
    raise ArgumentError, "'#{path}' is not a valid namespace" 
    end 
end 

的結果是,我現在可以做到以下幾點:

namespace "EIF::Core::Entities" 
class EIF::Core::Entities::Attirbute 
    #class code 
end 

現在來下一步。我想用一個紅寶石塊使事情更容易閱讀,因此它看起來就像:

namespace "EIF::Core::Entities" do 
    class Attribute 
    #class code 
    end 
end 

myAttribute = EIF::Core::Entities::Attribute.new 

的問題是,到目前爲止,唯一的方法我發現創建模塊在運行時是EVAL ,當我嘗試將代碼塊拖入eval中時,生成的類仍保留在根名稱空間中。我已經嘗試過instance_eval,module_eval和class_eval,並且由於某些原因,none都不會在模塊內創建類。

我能做到這一點嗎?我討厭現在放棄。

+2

爲什麼在__earth__你想要做這樣的事情?對於沒有經驗的隊友來說,學習實際的__ruby__結構會更好,而不是你想要創建的一些模糊的語法「插件」。 –

+0

因爲很有趣:D 哦,而且這是一個愛好項目。代碼並不是可重用的,這些人不是程序員開始(尚)。我想用DSL來簡化一些事情 – elite5472

+2

不,通過讓他們學習不夠 - 讓Ruby變得不那麼有趣,無論誰維護你的代碼都會讓你厭惡你。你的C代碼是否有'#define BEGIN {'和'#define END}'? –

回答

2

完成。

看來,當您添加使用module_eval類,如:

My::Namespace.module_eval do 
    class MyClass 
    end 
end 

爲MyClass的名稱空間解析不管上下文來::。然而,通過寫

class self::MyClass 

該命名空間解析到當前命名空間的對象,從而產生的類定義將是我::命名空間

我不知道爲什麼會這樣,但至少我有一些工作。現在問題在於,雖然這個時間較短,但self這個詞是反直覺的。