2012-11-05 67 views
1

我正在努力應對一個我無法確定的錯誤。訪問模板工具箱中的變量的奇怪問題

我有一個函數,需要一個郵政編碼,做一個查找,並返回一個緯度,經度和麪積的名稱。

例如,通過AD300它返回(類似)42.6,1.55,ordino - 它工作得很好。

的函數被調用是這樣的:

my ($lat, $lng, $area) = $object->release(); 

的返回值都很好,我可以在Perl與警告

warn "Area $area, $rellat, $rellng"; 

這工作正常打印。 「區域Ordino,42.6,1.55」

然後,我將這些值之一(例如$ area)添加到數據散列中,並將其傳遞到通過TT進行預處理的網頁中(正如我成功完成的那樣與其他變量的負載)。

我以正常的方式將值分配給散列。例如 $ hash - > {'area'} = $ area;

這裏是有趣的開始。當我嘗試引用TT中的值時,例如[%hash.area%] 我沒有在網頁上打印出「Ordino」,我被告知我已經通過了一個數組引用TT。

經過一些調試,我發現我的哈希變量hash.area,以某種方式引用了一個數組(依據TT),這個數組持有從子程序「release」返回的三個值。即 根據TT,hash.area = [42.6,1.55,ordino]。

也就是說,要在網頁中獲得值「Ordino」,我必須訪問[%hash.area.2%]。此外,我可以將$ hash - > {'area'}設置爲等於任何變量$ lat,$ lng或$ area並獲得相同的行爲。 TT認爲所有三個變量都引用相同的數組。即

$ LAT = $ LNG = $面積= [42.6,1.55,奧爾迪諾]根據TT

這是bizare,我可以愉快地打印在Perl的變量和它們顯示爲正常 - 不是一個數組。我試着用傾卸器傾倒哈希,沒有數組,一切都很好。然而不知何故,TT正在尋找一個陣列。這是我的頭腦。

該網站是相當大的,有很多頁面,我很高興地通過TT的變量和哈希值的網頁,並且已經4年了。我從來沒有見過這個。在其他頁面上,我甚至可以傳遞與「釋放」方法完全相同的輸出,並且它被正確處理。

我不要認爲我的TT處理代碼是問題,但以下是相關的。

my $tt = Template->new({ 
    INCLUDE_PATH => [ @$template_directories ], 
    COMPILE_EXT => '.ttc', 
    COMPILE_DIR => '/tmp/ttc', 
    FILTERS => YMGN::View->filters, 
    PLUGIN_BASE => [ 'YMGN::V::TT::Plugins' ], 
    EVAL_PERL => 1 
}); 

$self->{tt} = $tt; 
$self->{template_directories} = $template_directories; 
$self->{output} = $params->{output} || undef; 
$self->{data} = $params->{data} || []; 

上面創建了一個新的tt對象,並且是「新」函數的一部分(在下面重新引用)。 「數據」包含散列。 「輸出」保存已處理的模板準備發送給用戶瀏覽器。我們稱之爲new(above),處理數據並使用下面的代碼創建輸出。

sub process { 
my $self = shift; 
my $params = shift; 

if (!ref $self || !exists $self->{tt}) { 
    my $class = $self; 
    $self = $class->new($params); 
} 

if (!$self->{output}) { 
    die "You need to specify output"; 
} 

delete $self->{error}; 

$self->y->utils->untaint(\$self->{template}); 
my $rv = $self->{tt}->process(
    $self->{template}, 
    $self->{data}, 
    $self->{output}, 
    binmode => ':utf8', 
); 

if (!$rv) { 
    warn $self->{tt}->error(); 
    return { 
     error => $self->{tt}->error(), 
    }; 
} 
return 0; 
} 

以上都是消毒,因爲還有很多其他的東西在進行。 我相信重要的是進入的數據看起來是正確的,這裏是正在處理的完整數據的完整轉儲(在處理點)。導致問題的原因是bubbles - > [*] - > {'release'}(請注意,數據中的release ==區域,名稱因不相關的原因而更改)。正如你所看到的,傾銷者認爲這是一個字符串。 TT處理一切正常。

data $VAR1 = { 
     'system' => { 
        system stuff 
        }, 
     'features' => { 
         site feature config 
        }, 
     'message_count' => '0', 
     'bubbles' => [ 
        bless({ 
           'history' => [ 
              { 
               'creator' => '73', 
               'points' => '10', 
               'screenname' => 'sarah10', 
               'classname' => 'Flootit::M::Bubbles', 
               'id' => '1378', 
               'updated' => '1352050471', 
               'type' => 'teleport', 
               'label' => 'teleport', 
               'class' => 'Flootit::M::Bubbles' 
              } 
              ], 
           'creator' => '6', 
           'release' => 'Escaldes-Engordany', 
           'image' => 'http://six.flooting.com/files/833/7888.png', 
           'pop_time' => '1352050644', 
           'y' => $VAR1->{'y'}, 
           'taken_by' => '0', 
           'city' => '3', 
           'title' => 'hey a new bubble', 
           'id' => '566', 
           'class' => 'Flootit::M::Bubbles', 
           'prize' => 'go for it kids' 
          }, 'Flootit::M::Bubbles'), 
        bless({ 
           'history' => [ 
              { 
               'creator' => '6', 
               'points' => '10', 
               'screenname' => 'sarah20', 
               'classname' => 'Flootit::M::Bubbles', 
               'id' => '1723', 
               'updated' => '1349548017', 
               'type' => 'teleport', 
               'label' => 'teleport', 
               'class' => 'Flootit::M::Bubbles' 
              }, 
              { 
               'creator' => '6', 
               'points' => '5', 
               'screenname' => 'sarah20', 
               'classname' => 'Flootit::M::Bubbles', 
               'id' => '1732', 
               'updated' => '1349547952', 
               'type' => 'blow', 
               'label' => 'blow', 
               'class' => 'Flootit::M::Bubbles' 
              } 
              ], 
           'creator' => '89', 
           'release' => 'Ordino', 
           'image' => 'http://six.flooting.com/files/1651/8035.png', 
           'pop_time' => '1351203843', 
           'y' => $VAR1->{'y'}, 
           'taken_by' => '0', 
           'city' => '3', 
           'title' => 'test4', 
           'id' => '1780', 
           'class' => 'Flootit::M::Bubbles', 
           'prize' => 'asdfasdf dsadsasdfasdfasdf' 
          }, 'Flootit::M::Bubbles'), 
        bless({ 
           'history' => [], 
           'creator' => '6', 
           'release' => 'Andorra la Vella', 
           'image' => 'http://six.flooting.com/files/1671/8042.png', 
           'pop_time' => '0', 
           'y' => $VAR1->{'y'}, 
           'taken_by' => '0', 
           'city' => '3', 
           'title' => 'Pretty flowers, tres joli', 
           'id' => '1797', 
           'class' => 'Flootit::M::Bubbles', 
           'prize' => 'With lots of pretty pictures' 
          }, 'Flootit::M::Bubbles'), 
        bless({ 
           'history' => [], 
           'creator' => '6', 
           'release' => 'Hillrise Ward', 
           'image' => 'http://six.flooting.com/files/1509/8003.png', 
           'pop_time' => '0', 
           'y' => $VAR1->{'y'}, 
           'taken_by' => '0', 
           'city' => '3', 
           'title' => 'Test beats', 
           'id' => '1546', 
           'class' => 'Flootit::M::Bubbles', 
           'prize' => 'Sound great' 
          }, 'Flootit::M::Bubbles') 
        ] 
    }; 

處理後出來的東西是這樣的(在$輸出) 有一個 [IN氣泡%% FOREACH FLOOT]

周圍陣列(0xfaf5d448)浮動。

來自[%floot.release%]

如果我們使[%floot.release.2%]給出正確的值。

所有其他字段都可以被正確地引用 - 去圖。

將「氣泡」放在一起的代碼是;

my $bubbles = $y->model('Bubbles')->search(['type' => 'golden', 'image' => '!NULL', 
              'bubble_prizes' => ['p', { 'p.bubble' => 'self.id'}], ], { 
    order_by => '(created>CURRENT_DATE() AND thumbsup+thumbsdown<10) DESC, COALESCE(thumbsup,0)-COALESCE(thumbsdown,0) DESC, pop_time DESC', 
    count => 10, 
    fields => ['p.title as title', 'p.prize as prize', 'city', 'taken_by', 'pop_time', 'id', 'creator'], 
}); 

for (my $i=0; $i<@$bubbles; $i++) { 

    # Find specified bubbles (see below for when not found here) 
     my ($rellat, $rellng, $area) = $bubbles->[$i]->release() ; 
    $bubbles->[$i]->{'release'} = $area; 
} 
} 

然後,控制器需要$氣泡,與會話/網站的數據捆綁起來,所說的匿名散列內(如可以在上面的數據看到的)並將其傳遞到查看處理。

發佈的代碼是:

sub release { 
    my $self = shift; 
    my $postcode = $self->y->model('Prizes')->find({bubble => $self->id})->postcode; 
    my ($user_lat, $user_long, $region_name); 
    if($postcode) 
    { 
      ($user_lat, $user_long, $region_name) = $self->y->api('Location')->from_postcode($postcode); 
      return ($user_lat, $user_long, $region_name); 
     } 
    } 

API ::位置是相當大的,但相關的線;

$postcode_record = $self->y->model('GeoData')->find({ 
source => "ALL_COUNTRIES_POSTCODES", 
country => $country_code, 
sourceid => $postcode, }); 

return ($postcode_record->latitude, $postcode_record->longitude, $postcode_record->town); 

我已經顯示你從TT.pm(視圖的一部分)中獲取的數據轉儲。

那麼,任何想法可能會發生什麼或從哪裏開始?我能做些什麼來嘗試和進一步調試呢?我沒有想法。

+0

當你沒有發佈實際結束的代碼作爲TT的藏匿處時,很難猜測可能會出現什麼問題。含義:你顯示將'$ self - > {data}'解析爲TT的代碼。你顯示的代碼可以分配'$ self - > {data} = $ param {data} || []'(它本身看起來很腥意:TT期望hash ref,而不是array ref,作爲process的第二個參數),但是你不會在'$ param {data} '可能已被分配。 –

+0

我認爲這很明顯。 $ param - > {data}是一個hashref,$ param-> data包含一個(ref to a)散列,如$ hash {'area'} ='string value'所述。我不清楚你要求什麼? – mark

+0

我想@MoritzBunkus在說的是$ self - > {data} = $ params - > {data} || [];是有問題的,因爲如果$ params - > {data}(你說的是一個HashRef)是undef,那麼你正在創建一個空的ArrayRef「[]」。因此,根據具體情況,$ params - > {data}可以是ArrayRef或HashRef。你確定你不是指{}嗎? – oalders

回答

0

我發現問題在其他開發服務器和生產服務器上消失了。

因此,我嘗試卸載並重新安裝TT,但是這並沒有幫助。

因爲它似乎是我的開發者服務器上的一個環境問題,所以我退出了這個盒子並開始一個新的。

0

也許這是因爲$ area是一個有福的對象;試試這個轉換爲標字符串:

$string = ''.$area; 
# e.g. 
$hash->{'area'} = ''.$area; 

繼@Moritz評論,檢查$面積祝福:

print ref($area); 
use Data::Dumper; warn Dumper($area); 

和Q { 「」}超載:

print defined ${ref($area).'::'}{'(""'}; 

EDIT

sub release can return - undef if $ postcode evaluate to false - 但因爲它是在標量上下文中返回列表中的最後一個參數$ REGION_NAME像括號的列表(逗號表達式)

sub release { 
    my $self = shift; 
    my $postcode = $self->y->model('Prizes')->find({bubble => $self->id})->postcode; 
    my ($user_lat, $user_long, $region_name); 
    if($postcode) 
    { 
    ($user_lat, $user_long, $region_name) = $self->y->api('Location')->from_postcode($postcode); 
    return ($user_lat, $user_long, $region_name); 
    } 
} 

這將是有關傾倒$ REGION_NAME或$區,還是要看from_postcode 。

+0

除了簡單地將值強制爲一個字符串之外,OP還可以嘗試找出「$ area」是否實際上是有福的:例如,通過輸出'ref $ area'或類似'use Data :: Dumper;警告自卸車($面積);'。 –

+0

答案已更新 –

+0

嗨,謝謝,我已經嘗試了所有我能想到的沿着這些路徑包括上述的一切。我在絕望中嘗試了一些瘋狂的東西(比如將區域分配到一個新的散列,但仍然是相同的。我用我的數據轉儲編輯了這個問題 - 它對您來說看起來不錯嗎? – mark