Project

General

Profile

Actions

Feature #15559

open

Logical XOR (^^) operator

Added by baweaver (Brandon Weaver) about 5 years ago. Updated about 2 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:91234]

Description

Currently we have bitwise & and logical &&, and bitwise | and logical ||. Would it be possible to have logical ^^ in addition to the bitwise ^ for XOR?

Updated by mrkn (Kenta Murata) about 5 years ago

You can write expr1 ^^ expr2 as !expr1 != !expr2 in the current Ruby.
If both expr1 and expr2 are boolean, you can write expr1 != expr2.

I think ^^ can be useful for the case that both expr1 and expr2 are not boolean.
Have you ever write such conditional expressions?

Updated by mrkn (Kenta Murata) about 5 years ago

I think != is easier to understand than ^^.

Updated by mame (Yusuke Endoh) about 5 years ago

Would it be possible to have logical ^^ in addition to the bitwise ^ for XOR?

I think it is possible, but we need a good reason to do so. Do you have any use case?

Updated by sawa (Tsuyoshi Sawada) about 5 years ago

Unlike && and ||, which involve short-circuit evaluation, and hence are keywords rather than methods, the proposed ^^ will not involve short-circuit evaluation. Which is the intended proposal: as a keyword, or as a method?

Updated by indirect (André Arko) about 2 years ago

mrkn (Kenta Murata) wrote in #note-1:

I think ^^ can be useful for the case that both expr1 and expr2 are not boolean.
Have you ever write such conditional expressions?

Yes. Here is an example I encountered today. I have a class initializer that takes one argument: Foo.new(bar). Perhaps it looks like this:

class Foo
  def initialize(bar)
    @bar = bar
  end
end

I want to add another kind of initialization, with a keyword: Foo.new(baz: baz). That means I must allow bar to be nil. But I want to have only one of bar or baz. It is an error to provide both. Neither argument can be a boolean.

class Foo
  def initialize(bar = nil, baz: nil)
    raise ArgumentError unless bar ^^ baz
    @bar = bar || process_baz(baz)
  end
end

Updated by hmdne (hmdne -) about 2 years ago

Since we don't need short-circuit evaluation, we can simply use ^ for that reason. It's already defined on both TrueClass and FalseClass AND NilClass.

@indirect (André Arko) your example can be written as follows:

    raise ArgumentError unless !!bar ^ !!baz

Updated by hmdne (hmdne -) about 2 years ago

Hm, came into my mind that you may prefer to use this, more readable snippet instead:

    raise ArgumentError unless [bar, baz].one?

Updated by indirect (André Arko) about 2 years ago

hmdne (hmdne -) wrote in #note-6:

@indirect (André Arko) your example can be written as follows:

    raise ArgumentError unless !!bar ^ !!baz

You're just repeating the first comment on this thread. The entire point of this ticket is to have ^^ work on non-booleans, just like || and &&. Furthermore, your example is a bad one. If you want booleans, it's logically equivalent to only use a single exclamation point on each: !bar ^ !baz.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0