2011-04-22 9 views
8

可能性の重複:
How can I convert the stringified version of array reference to actual array reference in Perl?Perl:文字列を参照に変換しますか?

私は、文字列リテラルとして "SCALAR(0x8ec3a94)" を持っています。 Perlに を強制的に参照させて、それに従うことができますか?

IEの場合、Perlに「メモリ位置0x8ec3a94を見て、スカラーとして何かあれば を処理しますか?関連

Perl: Unwrapping list inside-out doesn't work?

そして、はい、私はこれを行うには恐ろしいことであると認識します。

+0

関連:http://stackoverflow.com/questions/1671281/how-can-i-convert-the-stringified-version-of-array-reference-to-actual-array-refe。それはまさにARRAYについてのものだったので、それは偽りではありません。 – Andy

+1

いいえ、参照はポインタではありません。どのように最初の場所で文字列になったのですか?それがバグです。 – shawnhcorey

+0

@ shawnhcorey、いいえそれはポインタではありませんが、同じ情報が含まれています、私の答えを参照してください –

答えて

3

最も近いのはTie::RefHashです。貧しい人のバージョンでは、ハッシュ

$registry{"$ref"} = $ref; 

内の参照を詰めて、後で

print ${ $registry{"SCALAR(0x8ec3a94)"} }, "\n"; 

このアプローチは欠点がたくさんあり、それを引き出します。どうしてこのようにしたいのですか?

+0

私は、最も内側の参照から始めて、自分の道を切り開いて、「内側から」何かを解析しようとしています。 – barrycarter

3

アンディのリンクから、Inline::C approachを試してみてください。 AV*ではなくSV*を使用しますが、動作するはずです。

私はそのリンクに示されているメソッドを拡張して、例をあざ笑っています。 Cの限られた知識で、参照が何も指さなくなったときにSegfaultを防ぐことができたと思います。(内側の中括弧をコメント解除し、$テキストを範囲外にすることでテストします。 CセクションでnewRV_incを使用しているため、$textの参照カウントが増分されます。したがって、$textが範囲外になっていても、見つかった参照($recovered_ref)がまだ存在する場合は、期待通りに値を使用できます(外側の中カッコのコメントを外してテストします)。

この方法は、どのような種類の参照でも機能するようです。オブジェクトについては不明ですが、必要ならばそれを行えます。詳細についてはperldoc Inline::Cが役に立ちますが、このパスを続けるには、perldoc perlguts、さらにはperldoc perlapiと読む必要があります。

#!/usr/bin/perl 

use strict; 
use warnings; 

use Inline 'C'; 

my $stringified_ref_text; 
my $stringified_ref_array; 
my $recovered_ref_text; 
my $recovered_ref_array; 

#{ 
    #{ 
    my $text = "Hello World"; 
    my @array = qw"Hello World!"; 

    $stringified_ref_text = \$text . ""; 
    $stringified_ref_array = \@array . ""; 

    print $stringified_ref_text . "\n"; 
    print $stringified_ref_array . "\n"; 
    #} 

    $recovered_ref_text = recover_ref($stringified_ref_text); 
    $recovered_ref_array = recover_ref($stringified_ref_array); 
#} 

print $$recovered_ref_text . "\n"; 
print "$_\n" for @$recovered_ref_array; 

sub recover_ref { 

    my $input = shift; 

    my $addr; 
    if ($input =~ /0x(\w+)/) { 
    $addr = hex($1); 
    } else { 
    warn "Could not find an address"; 
    return undef; 
    } 
    my $ref = _recover_ref($addr) or undef; 

    return $ref; 
} 

__DATA__ 
__C__ 

SV* _recover_ref(int address) { 
    if (address) 
    return newRV_inc((SV*) address); 

    return 0; 
} 
+0

デフォルトでは、StackOverflowはスコアでソートされた回答を表示してから、結びついた(明らかに)ランダムに決まります。これは、あなたが参照しているリンクがあなたの答えの下に表示されるかもしれないことを意味します。だから、あなたが意味するリンクを人々が知りたければ、それを「上のリンク」と呼んではいけません。 –

+0

@Daveは、私が投稿したのと同じリンクで、内の特定の回答だけを指しています。私は同じ質問に2つのリンクを掲示すべきですか?これはすべきです。 –

+1

私は、CPAN用のXSモジュールを作成してパッケージ化する簡単な理由を待っていました(数日前に最初の純粋なPerlモジュールをリリースしたばかりです)。これは人々がCPANで望むものでしょうか?それは私にそれを試みる理由を与えるだろう。 –

関連する問題