Merge only the set fields from one record into another.

← Operators and Expressions · Ref: Q1077

Implement :~: to guard each field, then merge:

  operator :~:
    -> from as Address
    if from.street?
      street :=: from.street
    if from.postcode?
      postcode :=: from.postcode
  addr :~: update

Only SET fields from the source are applied. Unset fields leave the target unchanged.

See Q1075 for :=: copy. See Q1058 for overview.

Example

defines module qa.operators.mergepartialrecord

  defines class

    Address
      street <- String()
      city <- String()
      postcode <- String()

      Address()
        ->
          street as String
          city as String
          postcode as String
        this.street :=: street
        this.city :=: city
        this.postcode :=: postcode

      //Constructor for partial updates — only postcode set
      Address()
        -> postcode as String
        this.postcode :=: postcode

      //Merge only copies SET fields from source
      operator :~:
        -> from as Address
        if from.street?
          street :=: from.street
        if from.city?
          city :=: from.city
        if from.postcode?
          postcode :=: from.postcode

      default operator ?
      default operator $
      default operator :=:

  defines program

    MergePartialRecordDemo()
      stdout <- Stdout()

      //Existing address with all fields set
      addr <- Address("10 High Street", "London", "SW1A 1AA")
      stdout.println(`Before: ${addr}`)

      //Partial update — only postcode is set via single-arg constructor
      update <- Address("EC2R 8AH")
      stdout.println(`Update: ${update}`)

      //Merge applies only the set postcode, leaves street and city alone
      addr :~: update
      stdout.println(`After merge: ${addr}`)

Common mistakes

E50060 — EK9 has no '.merge()' method; use the ':~:' operator to merge only the set fields of a record. See ek9 -h E50060 for details.

Incorrect:

      addr.merge(update)

Correct:

      addr :~: update
Other ways to ask this
  • Apply a partial update to an existing record using :~:
  • Patch a record with only the fields that have values
  • In Java I'd check each field for null before copying. What's the EK9 way?
  • I have an update object with some fields filled in and want to apply it to my main record

Coming from another language?

Java: manual null checks per field. Python: dict.update() with filtering. Go: manual field-by-field with zero-value checks. EK9: :~: merge operator with ? guards per field.

Keywords: partial, patch, :~:, guard, update, merge, set fields only