ansible var ref

What is this, yet another ansible quirk, or have I failed to RTFM closely enough? Either way, this doesn't feel intuitive so to help me understand I ran a little test to determine whether ansible assigns by reference, or assigns by value. Well... the answer is.... both?

Here's a small playbook to illustrate the concern:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - debug: msg="Original value of AH is {{ansible_host}}"
    - vars: { ansible_orig: "{{ansible_host}}", ansible_host: 203.0.113.5 }
      debug: msg="AH is {{ansible_host}} --- AO is {{ansible_orig}}"

Any guesses on what the value of AO is? Should it be 203.0.113.5 or 127.0.0.1?

TASK [debug] ***************************************
ok: [localhost] => {
    "msg": "Original value of AH is 127.0.0.1"
}

TASK [debug] ***************************************
ok: [localhost] => {
    "msg": "AH is 203.0.113.5 --- AO is 203.0.113.5"
}

Uh-oh! There's the quirk! When vars are assigned on the task, they seem to be assigned by reference. Either way, I don't fully understand it. If we use set_fact we can work-around the issue to make values more sticky (assign by value rather than, apparently, by reference).

---
- hosts: localhost
  gather_facts: no
  tasks:
    - debug: msg="Original value of AH is {{ansible_host}}"
    - set_fact: { ansible_orig: "{{ansible_host}}" }
    - vars: { ansible_host: 203.0.113.5 }
      debug: msg="AH is {{ansible_host}} --- AO is {{ansible_orig}}"

Which gives us a more intuitive result:

TASK [debug] *************************************
ok: [localhost] => {
    "msg": "Original value of AH is 127.0.0.1"
}

TASK [set_fact] **********************************
ok: [localhost]

TASK [debug] *************************************
ok: [localhost] => {
    "msg": "AH is 203.0.113.5 --- AO is 127.0.0.1"
}

and just for grins, I wondered if ansible (or more likely python) might process the variable assignment out of order, like maybe the vars dict was reordered alphabetically before the assignments happened? whatever is happening, I couldn't make much sense of it except that whatever I tried, I couldn't assign by value in the same task I was trying to change the value of a variable. I had to assign by value to a temporary variable in one task, and then I was free to change the value of a variable in the next task (while still keeping the original value in the temporary variable).