#4787 conversion from "dict" to "list" loses object types

obsolete: 8.5.9
closed-works-for-me
5
2015-01-13
2011-01-31
No

When we use "array get" a dict object is returned. If this is used directly in a foreach all types are preserved. The problem arises when the result is copied. It seems like the fix is to simply copy the objects as they are when converting from dict to list (tcl8.4.9 just appends the array object into the result list) rather than stringify the objects.

we are trying to upgrade our system from 8.4.9 to 8.5.9 and this is a blocker.

% array set a ""
% set a(b) "1"
1
% set a(c) [list 1 2]
1 2
% otype [array get a]
dict
% set l [array get a]
b 1 c {1 2}
% otype $l
dict
% otype $l
dict
% foreach key [array get a] { puts "[otype $key]" }
string
int
string
list
% otype $l
dict
% foreach key $l { puts "[otype $key]" }
string
string
string
string
% otype $l
list
% puts $l
b 1 c {1 2}
%

Discussion

  • Andreas Kupries

    Andreas Kupries - 2011-01-31

    I am not sure that it is the 'set l ...' which looses the type information of the elements. You are working interactively, and it may be the code printing the value to the terminal which does it.

    What is the output for

    % set l [array get a] ; foreach key $l { puts "[otype $key]" }

    This avoids the printing of 'l'.

     
  • Stephen Ehmann

    Stephen Ehmann - 2011-01-31

    It prints the right thing... Hmm...
    % array set a ""
    % set a(b) "1"
    1
    % set a(c) [list 1 2]
    1 2
    % set l [array get a] ; foreach key $l { puts "[otype $key]" }
    string
    int
    string
    list

    But separating them does not:
    % array set a ""
    % set a(b) "1"
    1
    % set a(c) [list 1 2]
    1 2
    % set l [array get a]
    b 1 c {1 2}
    % foreach key $l { puts "[otype $key]" }
    string
    string
    string
    string

    Why would list operations behave ok in this regard?
    % set l [list 1 [list 1 2]]
    1 {1 2}
    % otype $l
    list
    % otype [lindex $l 0]
    int
    % otype [lindex $l 1]
    list
    %

    I forgot to add that otype is a C function we wrote to print the type of the object and is implemented like this:
    if ( obj->typePtr ) {
    char* typeName = obj->typePtr->name;
    Tcl_SetResult(interp, typeName, TCL_VOLATILE);

    } else if ( obj->bytes ) {
    Tcl_SetResult(interp, (char*)"string", TCL_STATIC);

    } else {
    Tcl_SetResult(interp, (char*)"unknown", TCL_STATIC);
    }

     
  • miguel sofer

    miguel sofer - 2011-02-01
    • assigned_to: msofer --> dkf
     
  • Stephen Ehmann

    Stephen Ehmann - 2011-02-02

    puts $l
    also makes the issue appear.

     
  • Donal K. Fellows

    • status: open --> closed-invalid
     
  • Donal K. Fellows

    Seems to be working exactly as designed. We do not guarantee (and never have guaranteed) that the "type" of values will be preserved; it does not represent type information in the same way that a Python or Ruby object's type does.

     
  • Stephen Ehmann

    Stephen Ehmann - 2011-02-03

    Thanks, we need to rethink parts of our system that were relying on this... You can close this issue.

     
  • Stephen Ehmann

    Stephen Ehmann - 2011-02-03
    • status: closed-invalid --> open
     
  • Donal K. Fellows

    • status: open --> closed-works-for-me
     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks