Page 1 of 1

What does this syntax mean? hHead := {=>}

Posted: Tue Jul 02, 2019 11:59 pm
by James Bott
I just came across this syntax:

hHead := {=>}

I have never seen this before. First the prefix "h" usually signifies a handle. An empty array is {}. So what does the => mean?

So if Head is an empty array, then normally it is written like this:

aHead:= {}

Code was written by Daniel Garcia-Gil who seems to be incognito right now.

I searched the xHarbour header files for "=>" (without the quotes) and nothing was found.

Any ideas?

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 1:47 am
by cnavarro

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 3:08 am
by hua
From xHarbour's doc:

{=>}
Literal hash.

Syntax

Code: Select all

   {[<key1>] => [<value1>][,<keyN> => <valueN>]}
Arguments
<key1> .. <keyN>
<key> is one or more key values to initialize the Hash with. Key values may be of data type Character, Date or Numeric. Other data types are not allowed for <key>.
<value1> .. <valueN>
<value> is one or more values of any data type associated with <key> when the Hash is initialized. Multiple key/value pairs are separated with commas.

Description
An empty literal Hash is created with the characters {=>}. The Hash can be initialized with key => value pairs upon creation.

A Hash is similar to a two column array where the keys are stored in the left and the associated values in the right column. For this reason, a Hash is often referred to as "associative array". A Hash, however, is a genuine data type in xHarbour and allows for different operations than with the Array data type. The most significant difference between Hash and Array is that while values stored in an array are retrieved using a numeric ordinal position of an array element, a Hash value is retrieved by its associated key, and not by its ordinal position.

For this reason, data types for keys must be orderable. This restricts keys to the data types Character, Date and Numeric. A key, however, can be associated with a value of any data type, including Hash.

The most common data type for keys is Character. This makes a Hash to a kind of "lightweight object" that has only data and no methods. Since the key strings are used to retrieve the associated values, a key string can be understood like a message sent to an object.

The "dual" nature of the Hash data type, being partly similar to arrays and partly to objects, finds its expression also in the syntactical notation that can be used for retrieving a value from a Hash. Both operators are supported, the array element operator [ ] and the : send message operator. The latter, however, requires keys to be of data type Character.

Important: when using the : send message operator to create or retrieve a value from a Hash, the message is case-sensitive unless HSetCaseMatch() is set to .F. (false) for the Hash.

Info
See also: { }, Array(), CLASS, Hash()
Category: Operators , Special operators , xHarbour extensions
LIB: xhb.lib
DLL: xhbdll.dll
Examples

Code: Select all

// The example demonstrates how to create and populate hash values.

   PROCEDURE Main                      // literal hash
      LOCAL hHash := { "COM1" => 1, "COM2" => 2 }

      // object notation
      ? hHash:COM1                     // result: 1

      // array notation
      ? hHash["COM2"]                  // result: 2

      // adding a new key/value pair using object notation
      hHash:COM3 := 3

      ? hHash:COM3                     // result: 3

      ? hHash:COM4                     // runtime error
   RETURN

Code: Select all

// The example demonstrates comparison operators with hashes

   PROCEDURE Main
      LOCAL hHash1 := { "A" => 1, "B" => 2, "C" => 3, "D" => 4 }
      LOCAL hHash2 := { "B" => 5, "C" => 6, "E" => 7, "F" => 8 }
      LOCAL hHash3 := hHash1

      ? hHash1 == hHash2      // result: .F.
      ? hHash1 <> hHash2      // result: .T.

      ? hHash1 == hHash3      // result: .T.
      ? hHash1 <> hHash3      // result: .F.
   RETURN

Code: Select all

// The example demonstrates set-oriented operations with hashes
// using Plus and Minus operators

   PROCEDURE Main
      LOCAL hHash1 := { "A" => 1, "B" => 2, "C" => 3, "D" => 4 }
      LOCAL hHash2 := { "B" => 5, "C" => 6, "E" => 7, "F" => 8 }
      LOCAL hHash3

      hHash3 := hHash1 + hHash2
      ? ValToPrg( hHash3 )
      // { "A" => 1, "B" => 5, "C" => 6, "D" => 4, "E" => 7, "F" => 8 }

      hHash3 := hHash1 - hHash2
      ? ValToPrg( hHash3 )
      // { "A" => 1, "D" => 4 }
   RETURN

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 3:13 pm
by James Bott
Thanks both of you for your answers. It seems I need to do some reading about hashes. I know what they are but I have only used them once I think. And I don't really understand them.

The app I found this syntax in uses hashes a lot, but most of the arrays are only a few items long. I wonder how much of a speed increase that could provide. Not a noticeable amount I would think.

Where might they be commonly used with advantage over other methods?

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 3:56 pm
by Enrico Maria Giordano
As an example, hashes are useful with web services that require json data.

EMG

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 3:57 pm
by hua
For me readability and convenience because I don't have to declare all variables.

For instance, I declare a hash var just once
local hPerson := hash()

// after that I just immediately assign values to keys. If the key doesn't exist it will be auto added
hPerson["name"] := "Mike" // in xHarbour, you can write this as hPerson:name but if I'm not mistaken such notation won't auto create non-existent key
hPerson["gender"] := "M"
AddToDbf(hPerson)

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 5:14 pm
by Antonio Linares
James,

When we access an object data we use the data's name and not its index position (as objects datas are kept into arrays), thus
"hashes" (also known as "keyed collections") have been with us since Clipper 5.

hashes use this technology, that was already present in Clipper 5, to manage an array in a different way, that is accessed by "keys" instead of an index number.

So instead of doing aValues[ 5 ] think of it as aValues[ "five" ]. Its the same concept as doing aValues:five

This will help you to understand how this fit into the whole types of variables model. They are very usefull, once you start thinking in hashes way :-)

Image

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 9:02 pm
by vilian
Guys,
I'm trying to understand hash. Could you tell me what is wrong in this code bellow ?

Code: Select all

FUNCTION Start()
LOCAL oSif

    oSif := TNotaSif():New()
    oSif:aTotTrib["ICMV"] += 10 

RETURN nil

CLASS TNotaSif
  DATA aTotTrib INIT {=>}
  METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New() CLASS TNotaSif

   ::aTotTrib  := {"ISSB"=>0,"ISSV"=>0,"SUFB"=>0,"SUFV"=>0,"ICMB"=>0,"ICMV"=>0,"SUBB"=>0,"SUBV"=>0,"OUTB"=>0,"OUTV"=>0,;
                         "PISB"=>0,"PISV"=>0,"COFB"=>0,"COFV"=>0,"ISEB"=>0,"ISEV"=>0,"CIDB"=>0,"CIDV"=>0,"DIFB"=>0,"DIFV"=>0 }
RETURN self
 
When I do oSif["ICMV"] += 10 there is happening the error bellow:
Error BASE/1068 Argument error: array access

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 9:07 pm
by Enrico Maria Giordano

Code: Select all

oSif:aTotTrib["ICMV"] += 10
EMG

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 9:15 pm
by vilian
Thank you Enrico,

I fixed what you said, But still happening the same error.

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 9:29 pm
by Enrico Maria Giordano
Please double check and try again. Your second sample works fine here.

EMG

Re: What does this syntax mean? hHead := {=>}

Posted: Wed Jul 03, 2019 11:54 pm
by vilian
Thank you Enrico,

You are right ;)