Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Prettier for Ruby (2019)

Prettier for Ruby (2019)

A lightning talk describe @prettier/plugin-ruby, the choices that went into it, how it works, and how to use it.

Kevin Newton

August 13, 2019
Tweet

More Decks by Kevin Newton

Other Decks in Programming

Transcript

  1. github.com/prettier/plugin-ruby twitter.com/kddeisz What is prettier? • A language-agnostic framework for

    building formatters • A set of language-specific parsers that build a prettier- specific intermediate representation (IR) • A printer for printing out prettier IR
  2. github.com/prettier/plugin-ruby twitter.com/kddeisz Language support • JavaScript (JSX, Flow, TypeScript, JSON)

    • HTML (Vue, Angular) • CSS (Less, SCSS, styled-components, styled-jsx) • Markdown (MDX, YAML)
  3. github.com/prettier/plugin-ruby twitter.com/kddeisz Plugin support • Java (community) • PHP (official)

    • PostgreSQL (community) • Ruby (official) • Swift (official) • TOML (community)
  4. github.com/prettier/plugin-ruby twitter.com/kddeisz @prettier/plugin-ruby • A ruby gem and a node

    module • 612 GitHub stars, 2905 downloads/week on npm • Active development
  5. github.com/prettier/plugin-ruby twitter.com/kddeisz Ruby to prettier IR • Parse the Ruby

    source using ripper • Convert the ripper output to JSON and return to node • Walk the ripper tree with node to generate prettier IR • Ripper::SCANNER_EVENTS.size = 52 • Ripper::PARSER_EVENTS.size = 132
  6. github.com/prettier/plugin-ruby twitter.com/kddeisz Prettier IR to source • Walk the prettier

    IR and print nodes as you go • At each node, call the correct print function for that node from the necessary plugin/printer • If you hit the line limit, break the outermost group
  7. github.com/prettier/plugin-ruby twitter.com/kddeisz d = [ 30_644_250_780, 9_003_106_878, 30_636_278_846, 66_641_217_692, 4_501_790_980,

    671_24_603036, 131_61973916, 66_606629_920, 30_642_677_916, 30_643_069_058 ] a, s = [], $*[0] s.each_byte { |b| a << ('%036b' % d[b.chr.to_i]).scan(/\d{6}/) } a.transpose.each do |a| a.join.each_byte { |i| print i == 49 ? ($*[1] || '#') : 32.chr } puts end
  8. github.com/prettier/plugin-ruby twitter.com/kddeisz Ruby choices • For the most part, consistent

    with rubocop • Run on the same input it will generate the same output • It will never change the meaning of your program* *Probably
  9. github.com/prettier/plugin-ruby twitter.com/kddeisz array literals %w[alpha beta gamma delta epsilon] %i[alpha

    beta gamma delta epsilon] ['alpha', 'beta', 'gamma', 'delta', 'epsilon'] [:alpha, :beta, :gamma, :delta, :epsilon]
  10. github.com/prettier/plugin-ruby twitter.com/kddeisz %w[alpha beta gamma delta epsilon] %i[alpha beta gamma

    delta epsilon] %w[alpha beta gamma delta epsilon] %i[alpha beta gamma delta epsilon] array literals
  11. github.com/prettier/plugin-ruby twitter.com/kddeisz strings 'foo' "foo" 'foo\n' "foo\n" 'foo #{bar} baz'

    "foo #{bar} baz" 'foo \M-\C-a' "foo \M-\C-a" "#@foo" "#@@foo" "#$foo" ?f
  12. github.com/prettier/plugin-ruby twitter.com/kddeisz strings 'foo' 'foo' 'foo\n' "foo\n" 'foo #{bar} baz'

    "foo #{bar} baz" 'foo \M-\C-a' "foo \M-\C-a" "#{@foo}" "#{@@foo}" "#{$foo}" 'f'
  13. github.com/prettier/plugin-ruby twitter.com/kddeisz Ruby choices • break, next, yield, return don’t

    use parentheses
 (super will sometimes get parentheses) • no nested ternaries • decimal numbers will get underscores after 3 digits
 octal numbers will have an “o” added if it’s not there • {} lambdas for single line, do…end for multi-line • … and many more!
  14. github.com/prettier/plugin-ruby twitter.com/kddeisz Prettier options • Increase adoption • No longer

    done • Great demand from the community • Time to entrench • Compatibility reasons
  15. github.com/prettier/plugin-ruby twitter.com/kddeisz Ruby options • --add-trailing-commas = false • --inline-conditionals

    = true • --inline-loops = true • --prefer-hash-labels = true • --prefer-single-quotes = true
  16. github.com/prettier/plugin-ruby twitter.com/kddeisz Future work • Better comment handling • Better

    support for method chaining • Template language support (ERB, HAML, etc.)