Closed 14NGiestas closed 6 years ago
I am not really sure what you are trying to do. Do you populate the main dict in multiple subroutines? If yes, then the above code should concatenate the main dict
main_dict = main_dict // ('sub-dict1' .kvp. sub_dict)
In case you are dealing with allocatable
arrays or static arrays in subroutines and using kvp, then it won't work. I am not at my computer so I can't create a small example, but if you clarify a bit more I'll be able to help you.
Sorry I'll try to be more clear, I have a derived type which holds the main dict then I try to populate using a array of strings as key in that manner, in fact this works however the sub-dict do not keep the default values I provided.
subroutine (...)
do i=(...)
new_dict = (
array(i) .kvp. (
('value1' .kv. 0.d0) //
('value2' .kv. 'string')
)
)
self % main_dict = self % main_dict // (new_dict)
end do
(...)
end subroutine
I also tried to do the following:
new_dict = ('value1' .kv. 0.d0)//('value2' .kv. 'string')
self % main_dict = self % main_dict // (array(i) .kvp. new_dict)
In main program I try to retrieve the defaults:
type(dict) :: d
type(myderived) :: my
real :: r
character(255) :: buffer
! here I can retrieve all keys (populated by array(i))
! but can't retrieve the values of the sub dict
d = .first. my % main_dict
call assign(r, d, 'value1') ! non sense
call assign(buffer, d, 'value2') ! blank
print*, .key. d ! ok returns the right key name
@14NGiestas I am quite busy this week, if you can provide a complete test example I can more easily test it :)
Here it is a complete example... fdict-test.zip
Thanks! Your zip file says it is incomplete?
Archive: ~/fdict-test.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
Oops... I edited the previous comment adding the correct file
hmm, same error appears. Could you try and create a tar?
Using a online tool this time O_O EDIT: Fixed the example... fdict-test-3.zip
worked! ;) I'll have a look!
Ok, the problem is quite trivial. When you are using .first.
you are not retrieving the value of the first element in the dictionary. You are basically creating a new pointer to the dictionary starting from the first key. Then you can loop on this using:
type(Dict) :: main_dict
type(Dict) :: loop_dict
loop_dict = .first. main_dict
do while ( .not. .empty. loop_dict )
< do something with this key-val segment in the dictionary >
loop_dict = .next. loop_dict
end do
So your code should look like this:
module my_module
use dictionary
type MyType
type(Dict) :: main_dict
end type MyType
contains
function MyType_(array) result(self)
implicit none
type(MyType) :: self
type(Dict) :: sub_dict
character(*) :: array(:)
integer :: i
real(8) :: v
do i = 1 , size(array)
sub_dict = ('val1' .kv. 100.d0) // ('val2' .kv. 'A string')
self%main_dict = self%main_dict // (array(i) .kvp. sub_dict)
call nullify(sub_dict)
end do
end function MyType_
end module my_module
program main
use my_module
type(MyType) :: t
type(Dict) :: sub_dict, loop_dict
real(8) :: val
character(20) :: buffer
t = MyType_(['hello', 'world', 'then!'])
loop_dict = .first. (t%main_dict)
call associate(sub_dict, loop_dict)
call assign(buffer, sub_dict, 'val2')
call assign(val, sub_dict, 'val1')
print*, "Should print 100.0d0:", val
print*, "Should print 'A string':", buffer ! Should print "A string" ?
end program main
Thank you, Zerothi, it works! :smiley:
First of all: awesome work! A dict of a dict, in current implementation, seems to work flawlessly by reference (pointers). The problem in my use-case is that I need to create a new sub-dict and then assign to a main dict inside a subroutine.
That works in the main program but when in a subroutine or loop this simple don't work and I don't know why... my guess it's some variable is pointing to the variable new_dict then when the subroutine ends all data is thrown away since the new_dict variable is deallocated and now points to some garbage in memory.
There is a way to achieve automatic generation of dicts in current stage of development or a new function needs to be implemented?