2014-01-13 67 views
1

我有一個Perl程序想要在一堆其他文件中運行Perl代碼並獲取每個文件中設置的所有變量。在正常情況下,這些其他文件將位於它們自己的頁面中,例如,foo.pm中的package foo。然後我只是use foo,然後在%foo::周圍看看是什麼定義的。我的挑戰是其他文件不包含package聲明,並且無法修改。從其他不在包中的Perl程序中讀取變量

Perl程序如何在其他未指定package的Perl文件中運行代碼並獲取由它們設置的變量和值?

附加限制:

  • 必須在Perl 5.10.1及更高版本。從5.10.1開始的所有核心模塊都可用。

  • 必須在Linux上工作。 (我目前正在使用Red Hat 6,但確切的分佈可能會發生變化。)

  • 我想盡量減少此項目所依賴的數量。我打算添加一個或兩個額外的依賴項。

  • 我將處理多個文件。有必要讓其他文件不會污染父母的符號,也不會污染其他文件的符號。目標是防止意外損壞;我可以安全地假設其他文件不是惡意的。其他文件不會嘗試修改其他軟件包,儘管它們本身可能是use模塊。我願意忍受由運行其他文件代碼造成的其他副作用。

(我重新寫了這個問題更集中,第一幾點意見正在解決以前的版本。)

+1

它曾經是*所有* Perl程序員寫的模板和ORM庫。現在,這很可能重新發明輪子。首先由誰來編輯/管理模板數據,然後向後確定技術以及這些人員如何以足夠的細節訪問內容以完成他們的工作。使用更復雜的模板庫之一,然後使用數據庫作爲託管數據(在您的示例中爲'$ author'和'$ title'),您可能會更好。 –

+0

我當然寫了我自己的模板引擎。 :-)後來我變得聰明起來,轉移到Template Toolkit。 我很有可能會把它交給一個不熟練的Perl或其他我使用的人,但是會期望它能夠擴展,修復它,甚至完全替代它。除了基本的Linux系統之外,這個人可能沒有任何東西。所以移動部件越少越好。好的,用戶都是程序員,所以我可以逃脫更多的(例如Perl輸入文件)。 我的真正目標:不要讓下一個人像我當時那樣生氣。 :-) –

+0

不修改原始文件的約束限於原始位置中的原始文件。我可以修改內存中的其他文件並將修改後的版本保存在其他位置。我每次運行時都需要繼續使用原始版本。 –

回答

2

首先,必須:有必須是一個更好的方式來做你想做的。

如果您決定走這條路線,您的原始方法很容易擴展。只需使用構建的名稱評估每個文件(使用do),該文件的名稱不會與程序中使用的任何其他包相沖突,然後再檢查該包的符號表。在這個例子中,我命名的包__Scratch__::__1__Scratch__::__2

my $index = 0; 

for my $file (@files) { 
    my $pkg = sprintf '__Scratch__::__%d', ++$index; 
    my $code = "package $pkg; do \$file; %$pkg\::"; 
    my %symbol_table = eval $code; 
    # add error checking to taste... 
    print "Symbols defined after evaluating $file: ", 
     join(', ', keys %symbol_table), "\n"; 
} 
0

你說你不能修改文件,但是你可以修改的 - 文件的內存內容?

例如,如果/path/to/somefile.pm是你的非模塊文件中的一個,你可以不喜歡

open my $pm, "<", /path/to/somefile.pm or die; 
my @lines = <$pm>; 
eval(join("\n","package somefile;", @lines, "1;")); 

# now you could do something like 
somefile::afunction("hello"); 

現在你已經得到它加載到內存中像一個真正的包。 (好吧,不是正確包。)

相關問題