Skip to content

Instantly share code, notes, and snippets.

@baweaver
Created March 9, 2022 07:05
Show Gist options
  • Save baweaver/86554ac3298f285490059014db7dcb62 to your computer and use it in GitHub Desktop.
Save baweaver/86554ac3298f285490059014db7dcb62 to your computer and use it in GitHub Desktop.
Experimentation on what a code migration syntax might look like, ideally
module CodeMigrations
# Number isn't important, vague syntax, and not all
# of these are specifically Rails examples
version from: 4.0, to: 5.0
# The easiest case, literally A to B direct translation.
class FilterToAction < Migration
expect_translation(
"after_filter" => "after_action",
# ...snipped excess for example
"skip_before_filter" => "skip_before_action",
"skip_filter" => "skip_action_callback",
)
end
# This one is harder, but very very doable
class AssertBangToNot < Migration
expect { assert !x }.to_become { assert_not x }
end
# This one is much harder, and requires more knowledge of Ruby syntax
#
# `x.select { |v| v.even? }` becomes the AST:
# (begin
# (block (send (send nil :x) :select) (args (arg :v))
# (send (lvar :v) :even?))
#
# `x.select(&:even?)` becomes the AST:
# (send (send nil :x) :select (block-pass (sym :even?))))
#
# Meaning the wrapping elements are different, making it a
# much harder conversion to infer without building in a lot of
# Ruby knowledge of block vs block-pass shenanigans.
class ToShorthandBlock
expect { x.select { |v| v.even? } }.to_become { x.select(&:even?) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment