2011-08-16 16 views
5

ऐसा लगता है कि पर्ल केवल एक हैश की चाबियों के रूप में तार हो सकता है। (क्या यह पर्ल के एक निश्चित संस्करण में बदल गया है?) यह केवल कुंजी के रूप में तारों का उपयोग करने में सक्षम होने के लिए बहुत सीमित है। क्या होगा यदि मैं एक वस्तु या सरणी कुंजी होना चाहता था? पायथन में एक सरणी, टुपल, और अन्य ऑब्जेक्ट्स का उपयोग करना आसान है जो तुलनात्मक रूप से कर सकते हैं। पर्ल में समानता के लिए सरणी जैसी चीजों की तुलना करने की क्षमता है, इसलिए मुझे नहीं लगता कि उन्हें मानचित्रण-प्रकार कुंजी के रूप में क्यों उपयोग नहीं किया जा सकता है।क्या पर्ल में एक सहयोगी सरणी प्रकार है जिसमें किसी भी प्रकार की चाबी हो सकती है?

क्या पर्ल में किसी भी प्रकार का उपयोग करने का कोई तरीका नहीं है? क्या कोई मॉड्यूल है जो यह प्रदान करता है?

उत्तर

3

AFAIK पर्ल बस कुंजी को स्ट्रिंग करता है?

package Foo; 

use Moose; 
use overload ('""' => \&stringify); 

sub stringify { 
    return "xxx"; 
} 

package main; 

use v5.10; 
use Data::Dump 'pp'; 

my $foo = Foo->new; 
my $hash = {$foo => 'bar'}; 
say pp($hash); // { xxx => "bar" } 

इस तरह आप हैश कुंजी के रूप में जो कुछ भी चाहते हैं उसका भी उपयोग कर सकते हैं। यह thread on Perl Monks भी देखें।

समानता के लिए, equality operators in perlop पर एक नज़र डालें। == ऑपरेटर संख्यात्मक रूप से तुलना करता है, eq ऑपरेटर स्ट्रिंग की तुलना करता है। इसका मतलब है कि उदाहरण के लिए (4, 2) == (1, 2) सत्य है (scalar (4, 2)2 है), जो आपके लिए आश्चर्यचकित हो सकता है।

3

आपने जो कहा है उसके विपरीत, पर्ल में आपके द्वारा दावा किए जाने पर समानता के लिए सरणी जैसी चीज़ों की तुलना करने की क्षमता नहीं है। शुरुआत के लिए, पर्ल में सरणी समानता के लिए कोई परिभाषा नहीं है। और यदि परिभाषा को सरणी की सामग्री की तुलना करने की आवश्यकता होती है, तो पर्ल में अधिकांश चीजों के लिए समानता की परिभाषा नहीं होती है जो किसी सरणी में पाई जा सकती है।

निकटतम पर्ल समानता सरणी की परिभाषा के लिए है, उनका पता है। अगर ऐसा क्या आप उपयोग करना चाहते है, तो यह काफी आसान है:

$key = ['a', 'b']; 
$hash{$key} = [ $key, $val ]; # Prevents the key from being freed. 
print $hash{$key}[1]; 

अन्यथा, पर्ल यह आप पर निर्भर है छोड़ देता है कि तुम क्या उपयोग करने के लिए यह क्या प्रदान करता है आप के लिए मजबूर करने के बजाय चाहते हैं लागू करने के लिए। मैं दो मुख्य दृष्टिकोण देखता हूं।

एक बंधे हैश, मूल रूप से कोड हैश के इंटरफ़ेस को वास्तव में हैश तालिका के बिना प्रस्तुत करता है, किसी भी प्रकार के प्रकार का समर्थन कर सकता है। आप सरणी समानता के अपने संस्करण को परिभाषित करने के लिए इसका उपयोग कर सकते हैं। एक मौजूदा मॉड्यूल भी हो सकता है (हालांकि मुझे बहुत जल्दी खोज के बाद एक नहीं देखा गया था)।

एक और दृष्टिकोण एक ऐसा फ़ंक्शन बनाना होगा जो कुंजी अभिव्यक्ति से अनूठी कुंजी उत्पन्न करता हो।

sub key{ "@_" } # Overly simplistic? 
$hash{key('a', 'b')} = $val; 
print $hash{key('a', 'b')}; 
+0

पर्ल भी सरणियों की सामग्री की तुलना कर सकते: संदर्भ, अनिवार्य रूप से, और तर्क धागे भर में CLONEing के साथ काम कर और कचरा कुंजी का संग्रह) उदाहरण के लिए, के लिए प्रदान करता प्रिंट 'ठीक है' अगर ([ 'एक', 1 ] ~~ ['ए', 1]); –

3

हां, इसके लिए सीपीएएन पर 0 मॉड्यूल है: Tie::Hash::StructKeyed। यह पूरी संरचना को ध्यान में रखता है, लेकिन एक स्नैपशॉट के रूप में। प्रत्येक/कुंजी मूल संदर्भ वापस कर देगा।

1

हाँ, यह, fieldhashes (5.10+ के लिए Hash::Util::FieldHash और Hash::Util::FieldHash::Compat 5.10 से पहले के लिए) fieldhashes के रूप में अपने हैश रजिस्टर करने के लिए इस्तेमाल कर रहा है, और आप (यह numifies उन हैश के लिए एक प्रमुख के रूप में किसी भी संदर्भ का उपयोग कर सकते (और इस प्रकार, किसी भी वस्तु)

use Hash::Util qw/fieldhashes/; 
fieldhashes \my (%foo, %bar, %baz); 

my %data = (a => 1, b => 2, c => 3); 
my $stuff = {t => 2, u => 3, l => 9}; 
$foo{\%data} = 'x'; 
$foo{$stuff} = 'a'; 
$bar{\%data} = 'y'; 
$bar{$stuff} = 'b'; 
$baz{\%data} = 'z'; 
$baz{$stuff} = 'c'; 


print "$foo{\%data} $bar{\%data} $baz{\%data}\n"; 
print "$foo{$stuff} $bar{$stuff} $baz{$stuff}\n"; 
संबंधित मुद्दे

 संबंधित मुद्दे