asciidoctor / asciidoctor

:gem: A fast, open source text processor and publishing toolchain, written in Ruby, for converting AsciiDoc content to HTML 5, DocBook 5, and other formats.
https://asciidoctor.org
Other
4.71k stars 790 forks source link

Make Asciidoctor::Extensions.register a module_function #2676

Open vivien opened 6 years ago

vivien commented 6 years ago

Because register is defined inside class << self, it is currently not possible to write an extension like this:

require 'asciidoctor/extensions'

include Asciidoctor::Extensions

register do
  inline_macro :git do
    process do |parent, target, attrs|
      command = "git-#{ target }"
      create_anchor parent, command, :type => :link, :target => "https://git-scm.com/docs/#{ command }"
    end
  end
end

Much of the stdlib uses module_function, so we get used to it working like that. I think this seems more intuitive for anyone, instead of calling explicitly Asciidoctor::Extensions.register.

Can register and friends be considered module_function instead?

mojavelinux commented 5 years ago

The simplest way, of course, is to replace class << self with module_function. But I'm not convinced we want to export all the functions.

I came up with away to selectively export, while still keeping the methods defined in self. See #3198 and let me know what you think about that approach.

I wish Ruby had a way to promote a static method to a module function, but it doesn't seem to work that way. My workaround seems to be the next best thing.

mojavelinux commented 5 years ago

I have to ask, is this really saving you that may characters? The Extensions module doesn't really provide utility functions, so promoting them to top level functions feels out of place. I could see it if these were pure functions, but they aren't.