I guess, the answer to (1) is that the resulting DataFrame is
| A | B | C | fixed |
|---|---|---|---|
| 1 | true | 'a' |
[1, 1] |
| 2 | false | 'b' |
[1, 1] |
and without Ref it’d be
| A | B | C | fixed |
|---|---|---|---|
| 1 | true | 'a' |
1 |
| 2 | false | 'b' |
1 |
“Aliasing” of arrays (or any mutable objects, really) just means having different names (aliases) to refer to the same actual object in memory. I.e., if you mutate the array in any row in the fixed column, you’ll see the change everywhere in the column.
Compare to the following:
julia> aliased = fill([], 3)
3-element Vector{Vector{Any}}:
[]
[]
[]
julia> push!(aliased[1], :foo)
1-element Vector{Any}:
:foo
julia> aliased
3-element Vector{Vector{Any}}:
[:foo]
[:foo]
[:foo]
julia> nonaliased = [[] for _ in 1:3]
3-element Vector{Vector{Any}}:
[]
[]
[]
julia> push!(nonaliased[1], :foo)
1-element Vector{Any}:
:foo
julia> nonaliased
3-element Vector{Vector{Any}}:
[:foo]
[]
[]