Some details of hash manipulations:
HB_HCOPY() function copies a hash to another.
Syntax :
HB_HCOPY( <hsDestination>, <hsSource>, [<nStart>], [<nCount>] ) -> <hsDestination>
As noticed in syntax, copy operation may be limited by [<nStart>], [<nCount>] arguments.
But a hash may NOT built by “COPY” method; because <hsDestination> argument isn’t optional.
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hFruits2 := HB_HCOPY( hFruits ) // Argument error !
Though it’s possible in two steps:
hFruits2 := HB_HASH() // Built first an empty hash
hFruits2 := HB_HCOPY(hFruits2, hFruits ) // copy second onto first
As a result, for hash copy process two hashes should be exist:
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hFruits := HB_HCOPY( hFruits, hDays )
or
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hTarget := HB_HASH()
hTarget := HB_HCOPY( hTarget, hFruits )
hTarget := HB_HCOPY( hTarget, hDays )
HB_HMERGE() function merge two hashes.
Syntax:
HB_HMERGE( <hsDestination>, <hsSource>, <bBlock>|<nPosition> ) -> <hsDestination>
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hMerged := HB_HMERGE( hFruits, hDays )
hFruits :
1 days => sunday monday
2 fruits => apple cherry apricot
hTarget :
1 days => sunday monday
2 fruits => apple cherry apricot
AADD( hFruits[ "fruits" ], "melon" )
hFruits and hTarget :
1 days => sunday monday
2 fruits => apple cherry apricot melon
Result of above tests :
HB_HCOPY() and HB_HMERGE() doesn’t “physically” copy / merge hashes data; instead, copy / merge only by reference(s).
HB_HCLONE() function : Cloning (exact copy of) hashes.
Syntax:
HB_HCLONE( <hsTable> ) -> <hsDestination>
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hClone := HB_HCLONE( hFruits )
hClone : fruits => apple cherry apricot
AADD( hFruits[ "fruits" ], "melon" ) // Source changed
hClone : fruits => apple cherry apricot
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._./*
Hash Details - 1 Copy, Merge & Clone Hashes. */ #define NTrim( x ) IF( HB_ISNUMERIC( x ), LTRIM( STR( x ) ), x ) PROCEDURE Main() SET COLO TO "W/B" cLMarj := SPACE( 3 ) CLS ? "Copy one hash to another : HB_HCOPY() function : " ? "Syntax :",; "HB_HCOPY( <hsDestination>, <hsSource>, [<nStart>]," ? " [<nCount>] ) -> <hsDestination>" hFruits := { "fruits" => { "apple", "cherry", "apricot" } } hDays := { "days" => { "sunday", "monday" } } * hFruits2 := HB_HCOPY( hFruits ) // Argument error ! hFruits := HB_HCOPY( hFruits, hDays ) ListHash( hFruits, "Copied-1 (Fruits)" ) hDays[ "days" ] := "friday" ListHash( hFruits, "copied or referenced ?" ) hTarget := HB_HASH() hFruits := { "fruits" => { "apple", "cherry", "apricot" } } hDays := { "days" => { "sunday", "monday" } } hTarget := HB_HCOPY( hTarget, hFruits ) hTarget := HB_HCOPY( hTarget, hDays ) ListHash( hTarget, "Copied-2 ( Target )" ) AADD( hFruits[ "fruits" ], "melon" ) ListHash( hTarget, "copied or referenced ?" ) ? "Merge two hashes : HB_HMERGE() function : " ? "Syntax :",; "HB_HMERGE( <hsDestination>, <hsSource>, <bBlock>|" ? " <nPosition> ) -> <hsDestination>" hFruits := { "fruits" => { "apple", "cherry", "apricot" } } hDays := { "days" => { "sunday", "monday" } } hMerged := HB_HMERGE( hFruits, hDays ) ListHash( hFruits, "Merged (hFruits)" ) ListHash( hMerged, "Merged (hTarget)" ) AADD( hFruits[ "fruits" ], "melon" ) ListHash( hFruits, "Merged or referenced ? ( hFruits) " ) ListHash( hMerged, "Merged or referenced ? ( hMerged) " ) * * Result of above tests : * * HB_HCOPY() and HB_HMERGE() doesn't "physically" copy / merge hashes data; * * instead copy / merge only by reference(s). * ? "Cloning (exact copy of) hashes : HB_HCLONE() function : " ? "Syntax :",; "HB_HCLONE( <hsTable> ) -> <hsDestination>" hFruits := { "fruits" => { "apple", "cherry", "apricot" } } hClone := HB_HCLONE( hFruits ) ListHash( hClone, "Cloned" ) AADD( hFruits[ "fruits" ], "melon" ) ListHash( hClone, "Source changed" ) ? @ MAXROW(), 0 WAIT "EOF HashDetails-1.prg" RETURN // HashDetails-1.Main() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. PROCEDURE ListHash( hHash, cComment ) LOCAL x1Pair := NIL cComment := IF( HB_ISNIL( cComment ), '', cComment ) ? cComment, '' * ?? "-- Type :", VALTYPE( hHash ),'' * ?? "size:", NTrim ( LEN( hHash ) ) ? FOR EACH x1Pair IN hHash nIndex := x1Pair:__ENUMINDEX() x1Key := x1Pair:__ENUMKEY() x1Value := x1Pair:__ENUMVALUE() ? cLMarj, NTrim( nIndex ) * ?? '', VALTYPE( x1Pair ) ?? '', NTrim( x1Key ), "=>" * ?? '', VALTYPE( x1Key ) * ?? VALTYPE( x1Value ) IF HB_ISARRAY( x1Value ) AEVAL( x1Value, { | x1 | QQOUT( '', x1 ) } ) ELSE ?? '', NTrim( x1Value ) ENDIF NEXT ? REPL( "~", 32 ) RETURN // ListHash() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.