@ ProgramNode (location: (1,6)-(4,17)) ├── locals: [:string] └── statements: @ StatementsNode (location: (1,6)-(4,17)) └── body: (length: 2) ├── @ LocalVariableWriteNode (location: (1,6)-(1,31)) │ ├── name: :string │ ├── depth: 0 │ ├── name_loc: (1,6)-(1,12) = "string" │ ├── value: │ │ @ CallNode (location: (1,15)-(1,31)) │ │ ├── flags: ∅ │ │ ├── receiver: │ │ │ @ StringNode (location: (1,15)-(1,25)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: (1,15)-(1,25) = "<<-HEREDOC" │ │ │ ├── content_loc: (2,0)-(3,0) = " very long string\n" │ │ │ ├── closing_loc: (3,0)-(4,0) = " HEREDOC\n" │ │ │ └── unescaped: " very long string\n" │ │ ├── call_operator_loc: (1,25)-(1,26) = "." │ │ ├── name: :strip │ │ ├── message_loc: (1,26)-(1,31) = "strip" │ │ ├── opening_loc: ∅ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ │ └── operator_loc: (1,13)-(1,14) = "=" └── @ CallNode (location: (4,6)-(4,17)) ├── flags: ignore_visibility ├── receiver: ∅ ├── call_operator_loc: ∅ ├── name: :puts ├── message_loc: (4,6)-(4,10) = "puts" ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (4,11)-(4,17)) │ ├── flags: ∅ │ └── arguments: (length: 1) │ └── @ LocalVariableReadNode (location: (4,11)-(4,17)) │ ├── name: :string │ └── depth: 0 ├── closing_loc: ∅ └── block: ∅