I can't really help you with this. But I have these comments: - it sounds like this is probably a bug and it would be great if you can file an issue.
- however, to be of use (both for the mailing list and for bug reporting) you need a small, self-contained test case. Ideally it should not depend on any packages, files, etc. I usually do this by deleting more and more of the original code such that the issue persists (yes, this is painstaking). - coding style: is rType a type? If so, it would be more Julian to split up the long list of if-elseif...-end into methods and use dispatch. Mauro On Tue, 2015-08-11 at 23:18, Sayeed Tasnim <[email protected]> wrote: > Ah, sorry. There's a mistake in the highlighting. At the bottom of > read_object, it should actually be highlighted like this: > > elseif rType == defaultRType.RAWSXP > rawLength = readInt32(rr.reader) > result = RObject(readbytes(rr.reader, rawLength), is_raw = true) > > elseif rType == defaultRType.LANGSXP > result = RObject(None) > att_list = read_attribute_list(rr) # att_list returns nothing DataType > setAttributes(result, att_list) > > elseif rType == defaultRType.SYMSXP > symbol = read_symbol_or_string(rr) > push!(rr.symbols, symbol) > return RObject([symbol]) > > else > error("Unexpected type") > end > > if getAttributeFlag(typeTag) > att_list = read_attribute_list(rr) > setAttributes(result, att_list) > end > > return result > end > > On Tuesday, August 11, 2015 at 5:03:23 PM UTC-4, Sayeed Tasnim wrote: >> >> I'm working on some Julia code to read XDR data/files (something that >> might be generated from R using save). >> >> I have a function read_attribute_list to read the attributes associated >> with an R Object which returns a Dict. I also have a function read_object >> to read an R Object which calls read_attribute_list. >> >> function read_attribute_list(rr::RReader) >> result = Dict{String,RObject}() >> typeTag = get_type_tag(rr) >> >> defaultRType = RType() >> while getRType(typeTag) == defaultRType.LISTSXP >> tagFlag = getTagFlag(typeTag) >> tag = None >> >> if tagFlag >> tag = read_symbol_or_string(rr) >> end >> >> car = read_object(rr) >> if car != None >> result[tag] = car >> end >> >> typeTag = get_type_tag(rr) >> >> end >> >> if getRType(typeTag) != defaultRType.EMPTYTAIL && >> getRType(typeTag) != defaultRType.STRSXP >> error("Not Implemented") >> end >> >> return result # result remains a Dict here and can be printed right >> before >> end >> >> >> function read_object(rr::RReader) >> typeTag = get_type_tag(rr) >> lengthVar = 0 >> result = None >> rType = getRType(typeTag) >> >> defaultRType = RType() >> if rType == defaultRType.LGLSXP >> lengthVar = readInt32(rr.reader) >> boolValues = @data(bitunpack(falses(lengthVar))) >> for i in 1:lengthVar >> flag = read_integer(rr) >> if flag == 0 || flag == 1 >> boolValues[i] = !(flag == 0) >> elseif flag == None >> boolValues[i] = NA >> else >> error("Invalid boolean flag from XDR: $(flag)") >> end >> end >> >> result = RObject(boolValues) >> >> elseif rType == defaultRType.INTSXP >> lengthVar = readInt32(rr.reader) >> values = @data(zeros(Int32, lengthVar)) >> >> for i in 1:lengthVar >> value = read_integer(rr) >> if value == None >> values[i] = NA >> else >> values[i] = value >> end >> end >> >> result = RObject(values) >> >> elseif rType == defaultRType.REALSXP >> lengthVar = readInt32(rr.reader) >> values = @data(zeros(Float64, lengthVar)) >> >> for i in 1:lengthVar >> value = readFloat64(rr.reader) >> if isnan(value) >> values[i] = NA >> else >> values[i] = value >> end >> end >> >> result = RObject(values) >> >> elseif rType == defaultRType.CPLXSXP >> lengthVar = readInt32(rr.reader) >> complexValues = @data(zeros(Complex128,lengthVar)) >> >> for i in 1:lengthVar >> realVal = readFloat64(rr.reader) >> imaginaryVal = readFloat64(rr.reader) >> if !isnan(realVal) && !isnan(imaginaryVal) >> complexValues[i] = complex128(realVal, imaginaryVal) >> else >> complexValues[i] = NA >> end >> end >> >> result = RObject(complexValues) >> >> elseif rType == defaultRType.STRSXP >> lengthVar = readInt32(rr.reader) >> stringVector = @data(fill("", lengthVar)) >> >> for i in 1:lengthVar >> val = read_symbol_or_string(rr) >> stringVector[i] = val != None ? val : NA >> end >> >> result = RObject(stringVector) >> >> elseif rType == defaultRType.VECSXP >> lengthVar = readInt32(rr.reader) >> vectorObject = @data(fill!(Array(Any,lengthVar),None)) >> for i in 1:lengthVar >> vectorObject[i] = read_object(rr) >> end >> >> result = RObject(vectorObject) >> >> elseif rType == defaultRType.EXTPTRSXP >> readInt64(rr.reader) >> result = None >> >> elseif rType == defaultRType.RAWSXP >> rawLength = readInt32(rr.reader) >> result = RObject(readbytes(rr.reader, rawLength), is_raw = true) >> >> elseif rType == defaultRType.LANGSXP >> result = RObject(None) >> att_list = read_attribute_list(rr) # att_list returns nothing DataType >> setAttributes(result, att_list) >> >> elseif rType == defaultRType.SYMSXP >> symbol = read_symbol_or_string(rr) >> push!(rr.symbols, symbol) >> return RObject([symbol]) >> >> else >> error("Unexpected type") >> end >> >> if getAttributeFlag(typeTag) >> att_list = read_attribute_list(rr) >> setAttributes(result, att_list) >> end >> >> return result >> end >> >> >> As read_attribute_list is called, the attributes are read correctly and >> the Dict can be viewed by printing it right before the return statement. >> However, in the highlighted code for read_object, the att_list returned is >> a nothing DataType and the Dict that was visible before is lost. >> >> I can't figure out what would be causing this bug. Some things that I >> have tried that might be helpful: >> 1) Turn off gc(). I disable garbage collection and run the code. The >> behavior remains the same and nothing is returned. >> 2) Return a list of tuples instead. Instead of returning a Dict, I return >> Array{(String,RObject)} to serialize the Dict. The behavior remains the >> same and nothing is returned. >> 3) Reproduce the bug outside of the module. I extract the part of the XDR >> file with only the attributes. read_attribute_list reads properly and >> returns the Dict. >> >> Feel free to ask questions about other pieces of the code or >> implementation details. Any help with this would be appreciated! >>
