ऐसा लगता है कि आप get_record_field(Field, SomeRecord)
जैसे कुछ करने में सक्षम होना चाहते हैं, जहां Field
उपयोगकर्ता इंटरफ़ेस कोड द्वारा रनटाइम पर निर्धारित किया गया है।
आप सही हैं कि आप मानक एरलांग में ऐसा नहीं कर सकते हैं क्योंकि रिकॉर्ड और record_info
फ़ंक्शन का विस्तार और संकलन समय पर समाप्त हो गया है।
कुछ ऐसे समाधान हैं जिनका मैंने उपयोग किया है या देखा है। मेरे समाधान इस प्रकार है: rec_test.erl
तुम भी विस्तार कर सकते हैं:
%% Retrieves the value stored in the record Rec in field Field.
info(Field, Rec) ->
Fields = fields(Rec),
info(Field, Fields, tl(tuple_to_list(Rec))).
info(_Field, _Fields, []) -> erlang:error(bad_record);
info(_Field, [], _Rec) -> erlang:error(bad_field);
info(Field, [Field | _], [Val | _]) -> Val;
info(Field, [_Other | Fields], [_Val | Values]) -> info(Field, Fields, Values).
%% The fields function provides the list of field positions
%% for all the kinds of record you want to be able to query
%% at runtime. You'll need to modify this to use your own records.
fields(#dns_rec{}) -> fields(dns_rec);
fields(dns_rec) -> record_info(fields, dns_rec);
fields(#dns_rr{}) -> fields(dns_rr);
fields(dns_rr) -> record_info(fields, dns_rr).
%% Turns a record into a proplist suitable for use with the proplists module.
to_proplist(R) ->
Keys = fields(R),
Values = tl(tuple_to_list(R)),
lists:zip(Keys,Values).
यह है कि संकलित का एक संस्करण यहाँ उपलब्ध है (उदाहरण के inet_dns.hrl
से #dns_rec
और #dns_rr
रिकॉर्ड के क्रम पहुँच देता है) ets:select/2
या mnesia:select/2
के साथ उपयोग के लिए मिलान के लिए गतिशील पीढ़ी के लिए यह गतिशील फ़ील्ड लुकअप नीचे दिखाया गया है:
%% Generates a matchspec that does something like this
%% QLC psuedocode: [ V || #RecordKind{MatchField=V} <- mnesia:table(RecordKind) ]
match(MatchField, RecordKind) ->
MatchTuple = match_tuple(MatchField, RecordKind),
{MatchTuple, [], ['$1']}.
%% Generates a matchspec that does something like this
%% QLC psuedocode: [ T || T <- mnesia:table(RecordKind),
%% T#RecordKind.Field =:= MatchValue]
match(MatchField, MatchValue, RecordKind) ->
MatchTuple = match_tuple(MatchField, RecordKind),
{MatchTuple, [{'=:=', '$1', MatchValue}], ['$$']}.
%% Generates a matchspec that does something like this
%% QLC psuedocode: [ T#RecordKind.ReturnField
%% || T <- mnesia:table(RecordKind),
%% T#RecordKind.MatchField =:= MatchValue]
match(MatchField, MatchValue, RecordKind, ReturnField)
when MatchField =/= ReturnField ->
MatchTuple = list_to_tuple([RecordKind
| [if F =:= MatchField -> '$1'; F =:= ReturnField -> '$2'; true -> '_' end
|| F <- fields(RecordKind)]]),
{MatchTuple, [{'=:=', '$1', MatchValue}], ['$2']}.
match_tuple(MatchField, RecordKind) ->
list_to_tuple([RecordKind
| [if F =:= MatchField -> '$1'; true -> '_' end
|| F <- fields(RecordKind)]]).
उल्फ वाइगर ने एक parse_transform, Exprecs भी लिखा है, जो आपके लिए स्वचालित रूप से कम या ज्यादा करता है। मैंने कभी कोशिश नहीं की है, लेकिन उल्फ का कोड आमतौर पर बहुत अच्छा होता है।
यदि आप एक psuedo-code उदाहरण देते हैं जो आप करना चाहते हैं तो यह मदद करेगा। – archaelus