--- title: "Super Secret Methods" layout: post date: 2017-07-16 snippet_source: "code/super_secret_methods.rb" --- Here is a quirk of the Ruby language that I discovered a few weeks ago. Method names can not contain a period character. ```ruby {% include_snippet singleton_def_bad %} ``` This is because the period character is syntax used for defining methods on specific objects. ```ruby {% include_snippet singleton_def_ok %} ``` Even though the _syntax_ does not allow periods in the method name, surprisingly, the Ruby _runtime_ will allow it. Using `define_method`, the syntax limitations can be bypassed. ```ruby {% include_snippet define_method_with_dot %} ``` The method above can't be called using normal Ruby syntax. ```ruby {% include_snippet call_secret_method_bad %} ``` But again, the syntax limitations can be bypassed, using `send`. ```ruby {% include_snippet call_secret_method_ok %} ``` To summarize, it is possible to define and call methods that are impossible to access via normal Ruby syntax. ~~Abuses~~ Applications ----------------------- Upon discovering this, my first thought was "this is a bug in Ruby." My next thought, of course, was "what could I use this for?" The only use that I can think of is avoiding method pollution. Sometimes, when writing mixins or base classes, you want to define methods for internal use _only_. You don't want these internal methods to accidentally override or conflict with other peoples' methods. > Roda is very concerned about pollution. [...] > Roda purposely limits the instance variables, > methods, and constants available in the route block scope, so that it is > unlikely you will run into conflicts. If you've ever tried to use an instance > variable named @request inside a Sinatra::Base subclass, you'll appreciate that > Roda attempts to avoid polluting the scope. > > — [Roda documentation](http://roda.jeremyevans.net/) > {:.author} > So this trick can be used to make "secret" methods which don't pollute the namespace of normal methods – although the same trick does not work for instance variables or constants. ```ruby {% include_snippet bad_ivar_set %} {% include_snippet bad_const_set %} ``` Disclaimer ---------- I'm sure someone's already frothing at the keyboard, writing a mean-spirited comment on Reddit, for daring to suggest that this trick _might_ be useful in any way. So let me be clear: this is probably a bad idea. I'm still not convinced that it is intended behaviour. I know that [method names are allowed to contain unicode](table_flip), but allowing the period character seems inconsistent to me, since it's not allowed for instance variables or constants. I also haven't tried it on JRuby, or any other implementations. It might only work on MRI. It's just an interesting insight into the internals of Ruby. [table_flip]: https://github.com/mperham/sidekiq/blob/b79e87bdfe433f5e3c7f4ce9cca4e3cdc3d79428/lib/sidekiq.rb#L52-L54