what is wrong with this code setting a nested record? FOLLOW UP
Håkan Stenholm
hakan.stenholm@REDACTED
Thu Jul 21 23:23:39 CEST 2005
MEENA SELVAM wrote:
>I have a function display_login2(A) where A is
>follows:
>(The arg and header record definitions are given at
>the end.)
>
>
>
>A= {arg,#Port<16338.534>,
>
>> {headers,undefined,
>> "image/gif,
>>image/x-xbitmap, image/jpeg, image/
>>pjpeg, */*",
>> "www.msn.com",
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> "Mozilla/4.0
>>(compatible; MSIE 6.0; Windows NT
>>5.1)",
>> undefined,
>> [],
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> undefined,
>> [{http_header,
>> 0,
>>
>>"X-Yaws-Had-Clicert",
>> undefined,
>> "false"},
>> {http_header,
>> 49,
>>
>>'X-Forwarded-For',
>> undefined,
>> "11.10.1.107"},
>> {http_header,
>> 7,
>> 'Via',
>> undefined,
>> "1.1
>>
>www.msn.com
>
>>(Alteon iSD-SSL/5.5)"},
>> {http_header,
>> 0,
>>
>>"X-Forwarded-By",
>> undefined,
>> "47.80.18.95"},
>> {http_header,
>> 10,
>>
>>'Accept-Encoding',
>> undefined,
>> "gzip,
>>deflate"},
>> {http_header,
>> 11,
>>
>>'Accept-Language',
>> undefined,
>> "en-us"}]},
>>
>>{http_request,'GET',{abs_path,"/"},{1,1}},
>> undefined,
>> "/",
>> [],
>> undefined,
>>
> ....
>
>> .... and much more
>>
>>
>-record(arg, {
> clisock, %% the socket leading to the
>peer client
> headers, %% headers
> req, %% request
> .....
> .....
> .....
> }).
>
>-record(headers, {
> connection,
> accept,
> host, %% host header
> if_modified_since,
> ...
> ...
> ...
> other = [] %% misc other headers
> }).
>
>I need to replace the host header (which is
>www.msn.com) by the redirected ip 47.80.18.95(which is
>part of the Other Header)
>
>Is this the only way to do this:
>Create a new record of type headers, with www.msn.com
>replaced by the 47.80.18.95
>
Yes
>
> NewHeader =
> (A#arg.headers)#headers{host="47.80.18.95"},
>
>[ typically i will make host as extracted from 3rd
>element of other header]
>
>Create 9 other new records of the 9 different types
>of the sub records of arg record. (Totally I have 10
>including headers)
>
>Newclisock = A#arg.clisock
>Newreq = A#arg.req
>...
>..
>
>
>Now create a new record of type Arg , by using the
>newly created 10 records like this:
>ANew = #arg{clisock = NewClisock,
> headers = NewHeader,
> req = NewReq
> ...
> ...},
>
There is no need to extract all the field values (sub records), it is
sufficient to only set the fields that need to be updated e.g.:
%% possibly get some sub records from A
...
%% do some code that creates new values for some fields (sub records)
NewReq = ...
NewVal = ...
%% update record (or rather creat a new one based on the old one)
%% with only the affected fields changed
ANew = A#arg{clisock = NewVal, req = NewReq},
...
>
>and use Anew instead of A from now on.
>
Use ANew when the updated version is needed and A when the old version
is needed - both are available in the current function clause scoop,
from the point that they are declared until the end of the clause.
No variable in a function clause can change its content after it has
been given a value in that scoop - updating values in each iteration
step is achived by passing updated values as arguments to the next
recursive call, so variables in the current scoop never change.
%% a simple list length calculation function, a accumulator is used to
%% make the function tail recursive (and to show how data is passed between
%% each iteration / recursive call)
length(List) ->
length(List, 0).
length([], Length) -> Length; %% base case - end of list found,
%% return the length value that has been
accumulated
length([_|R], Length) -> length(R,Lenght+1). %% pass new length and list
remainder
%% to next call of length/2
>
>Will this work? Also, is the syntax right while I am
>creating ANew?
>
>
>
>--- Håkan Stenholm <hakan.stenholm@REDACTED>
>wrote:
>
>
>>MEENA SELVAM wrote:
>>
>>
>>>Hi,
>>>
>>>the parameter A is of record type arg, which
>>>
>>contains
>>
>>>a subrecord of type, headers and which has a field
>>>host:
>>>
>>>The host field initially contains www.msn.com, and
>>>
>>I
>>
>>>am trying to overwrite with 47.80.18.95, but the
>>>following code doesnt work.. it still has
>>>
>>www.msn.com
>>
>>>itself.
>>>
>>>display_login2(A, ReplyMsgs, URL, IP, FromLogout)
>>>
>>->
>>
>>> (A#arg.headers)#headers{host="47.80.18.95"},
>>>
>>>am i doing anything wrong here?
>>>
>>>
>>>
>>It should work (see my test code below), but may
>>have forgotten to do:
>>
>> NewHeader =
>>(A#arg.headers)#headers{host="47.80.18.95"},
>> ...
>> xxx(NewHeader, ...) %% use the new
>>(updated) Header rather
>>than the old one in A
>> ...
>>
>>It would be helpful to see a bit more of your code,
>>I get the feeling
>>that your trying to do a destructive update on a
>>record in a single
>>assignment language, this won't work - data elements
>>in Erlang can only
>>be created but never modified[1] (with the exception
>>for
>>ets/mnesia/process dictionaries which can
>>conceptually be viewed as
>>processes storing data in some regular Erlang data
>>type like a binary
>>tree - which is updated by creating new nodes and
>>leaves to replace the
>>old ones - rather than overwriting old ones).
>>
>>[1] : deletion is done by the GC.
>>
>>================== test.erl =====================
>>
>>-module(test).
>>
>>-export([test/0]).
>>
>>-record(foo, {
>> bar
>> }).
>>
>>-record(bar, {
>> a,
>> b
>> }).
>>
>>test() ->
>> Bar = #bar{a = 1, b = 2},
>> Foo = #foo{bar = Bar},
>>
>> io:format("Foo = ~p~n", [Foo]),
>>
>> %% create new bar record
>> %% access foo record and create new bar record
>>based on foo.bar
>> Bar2 = (Foo#foo.bar)#bar{b = new_val},
>> io:format("Bar2 = ~p~n", [Bar2]),
>>
>> %% create new foo record
>> %% create new foo record containing the new Bar2
>>bar record
>> Foo2 = Foo#foo{bar = Bar2},
>> io:format("Foo2 = ~p~n", [Foo2]),
>>
>> ok.
>>
>>================== test.erl =====================
>>
>>2> c(test).
>>{ok,test}
>>3> test:test().
>>Foo = {foo,{bar,1,2}}
>>Bar2 = {bar,1,new_val}
>>Foo2 = {foo,{bar,1,new_val}}
>>ok
>>
>>
>>>meena
>>>
>>>
>>>__________________________________________________
>>>Do You Yahoo!?
>>>Tired of spam? Yahoo! Mail has the best spam
>>>
>>protection around
>>
>>>http://mail.yahoo.com
>>>
>>>
>>>
>>>
>>
>
>
>
>
>__________________________________
>Do you Yahoo!?
>Yahoo! Mail - Find what you need with new enhanced search.
>http://info.mail.yahoo.com/mail_250
>
>
More information about the erlang-questions
mailing list