sodapopcan
Improve this `unpipe` function?
I go through bouts of playing around with re-writing source-code using Sourceror. It generally goes: I learn a whole bunch, start getting comfortable with it, stop doing it for many months and forget everything ![]()
I’m back at it and just finished creating a function that will inline single pipes. IE:
socket
|> assign(:foo, "foo")
becomes:
assign(socket, :foo, "foo")
I was looking to get some feedback on my solution.
I initially thought I could get away with simply pre- or postwalking with some clever pattern-matching, but that proved to be difficult for me. I ended up using a zipper which made life a LOT easier getting me to a solution quite quickly. There are still a few issues with line-length but I’m otherwise quite happy with the clarity of it.
Still, I’m wondering:
- Is this possible using walking with an accumulator?
- Do you have a solution that’s different/better than mine?
- Do you have any other feedback?
TIA
def unpipe(ast) do
Sourceror.Zipper.zip(ast)
|> Sourceror.Zipper.traverse(fn
%{node: {:|>, _, _} = node} = zipper ->
prev = Sourceror.Zipper.prev(zipper)
next = Sourceror.Zipper.next(zipper)
with false <- match?(%{node: {:|>, _, _}}, prev),
false <- match?(%{node: {:|>, _, _}}, next),
{:|>, _, [var, {func, meta, args}]} <- node do
Sourceror.Zipper.replace(zipper, {func, meta, [var | args]})
else
_ ->
zipper
end
zipper ->
zipper
end)
|> Sourceror.Zipper.topmost_root()
end
Most Liked
sodapopcan
Ok, I may be celebrating early but simply setting empty meta solved it.
{:|>, _, [var, {func, _, args}]} <- node do
Sourceror.Zipper.replace(zipper, {func, [], [var | args]})
slouchpie
You can also use styler | Hex to fix single pipes.
zachdaniel
Ah, right. I think what you can do is check if the node previous to the top node is {:__block__, meta, [just_one_thing]} and if so, replace that node instead? Might mess w/ your traversal though.
sodapopcan
zachdaniel
Based on your proclivity for source code rewriting, you may also be interested in the igniter project ![]()
It’s similar to recode in some ways, but designed for building generators, installers, and upgraders. GitHub - ash-project/igniter







