6

The question is: Can I define my own custom operator in Ruby, except for the ones found in "Operator Expressions"?

For example: 1 %! 2

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Dima Knivets
  • 2,418
  • 7
  • 28
  • 40
  • I'm just learning it, and haven't tried. But i've read [here](http://stackoverflow.com/questions/5556124/ruby-defining-operator-procedure/5556215#5556215) that i can't define such methods. Can you give me an example? – Dima Knivets Aug 08 '12 at 23:21
  • [Here](http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-operators-and-their-methods/) is a decent article discussing the topic. – rudolph9 Aug 08 '12 at 23:25
  • Thanks for the article, but it's not what I'm asking about. – Dima Knivets Aug 08 '12 at 23:27
  • [This](http://stackoverflow.com/a/43429202/7324619) lets you do `a |op| b` using some overloading tricks. – Asone Tuhid Apr 15 '17 at 18:07

3 Answers3

8

Yes, custom operators can be created, although there are some caveats. Ruby itself doesn't directly support it, but the superators gem does a clever trick where it chains operators together. This allows you to create your own operators, with a few limitations:

$ gem install superators19

Then:

require 'superators19'

class Array
  superator "%~" do |operand|
    "#{self} percent-tilde #{operand}"
  end
end

puts [1] %~ [2]
# Outputs: [1] percent-tilde [2]

Due to the aforementioned limitations, I couldn't do your 1 %! 2 example. The Documentation has full details, but Fixnums can't be given a superator, and ! can't be in a superator.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • That's what I was asking about :) – Dima Knivets Aug 09 '12 at 10:56
  • as far as i can tell, the way superators works is actually to send your custom operator as an argument to an extended core operator as the real method. so you're not really creating a new operator, but it is a clever way to use ruby's core features :) – Alex Moore-Niemi Dec 03 '14 at 03:48
5

No. You can only define operators already specified in ruby, +,-,!,/,%, etc. (you saw the list)

You can see for yourself this won't work

def HI
  def %!
    puts "wow"
  end
end

This is largely due to the fact that the syntax parser would have to be extended to accept any code using your new operator.


As Darshan mentions this example alone may not be enough to realize the underlying problem. Instead let us take a closer look at how the parser could possibly handle some example code using this operator.

3 %! 0

While with my spacing it may seem obvious that this should be 3.%!(0) without spacing it becomes harder to see.

3%! can also be seen as 3.%(0.!) The parser has no idea which to chose. Currently, there is no way easy way to tell it. Instead, we could possibly hope to override the meaning of 3.%(0.!) but this isn't exactly defining a new operator, as we are still only limited to ruby's parsable symbols

diedthreetimes
  • 4,086
  • 26
  • 38
  • Thanks for the reply. Then, it's not logical that I have the ability to override built-in operators, but can't create my own. – Dima Knivets Aug 08 '12 at 23:30
  • 3
    Not logical? When the parser encounters any operator it is actually syntactic sugar for a method call. Thus method dispatch rules apply like normal. Defining built in operators is simply defining your own method to take advantage of this sugar. Defining new operators requires the parser to know how to parse your new operator. For example what does it do with `var%!`. Is this `var.send(:%).send(:!)` or `var.send(:%!)`. Does this make sense? – diedthreetimes Aug 08 '12 at 23:34
  • But, can I use this operator as following: `var.%!=("one")`? – Dima Knivets Aug 08 '12 at 23:46
  • No, % and ! are both reserved, and can not be part of method names (unless they are one of the established operators). Again this is to prevent un-parcable syntax. – diedthreetimes Aug 08 '12 at 23:49
  • Every special symbol is reserved? Even `€`, for example? – Dima Knivets Aug 08 '12 at 23:52
  • Actually, `!` can be in a method name. – edgerunner Aug 08 '12 at 23:55
  • Try it. It's easy enough. I don't have a source, but I'm pretty sure the answer is yes symbols are not allowed. Of course you could just make a one letter name say `def e`. – diedthreetimes Aug 08 '12 at 23:55
  • This isn't exactly true. The fact that you can't define a method named `%!` is hardly proof that custom operators are impossible. See my answer for a gem that makes it easy to create many custom operators, with some limitations. – Darshan Rivka Whittle Aug 09 '12 at 02:41
  • @DarshanComputing good point, I've expanded my answer to give more details on the issue. – diedthreetimes Aug 09 '12 at 03:31
  • @edgerunner Thanks. Your answer is now a much better explanation for why operators that would require being parsed differently aren't possible. (The specific example in the question falls into the category.) However, your answer is still incorrect about the actual question being asked. (Many) new custom operators are indeed possible, as explained in my answer. The documentation to the superators gem (linked to in my answer) explains how it works (with a chain of operators). – Darshan Rivka Whittle Aug 09 '12 at 04:04
1

You probably can't do this within Ruby, but only by modifying Ruby itself. I think modifying parse.y would be your best bet. parse.y famtour

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338