Issue #12753 has been updated by naruse (Yui NARUSE).

Status changed from Open to Assigned
Assignee set to matz (Yukihiro Matsumoto)
Target version set to 2.5

A patch is as follows:

```diff
diff --git a/numeric.c b/numeric.c
index 1858113c09..511155a3ac 100644
--- a/numeric.c
+++ b/numeric.c
@@ -3209,6 +3209,45 @@ int_even_p(VALUE num)
     return Qfalse;
 }
 
+/*
+ *  call-seq:
+ *     int.allbits?(mask)  ->  true or false
+ *
+ *  Returns +true+ if all bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_allbits_p(VALUE num, VALUE mask)
+{
+    return rb_int_equal(rb_int_and(num, mask), mask);
+}
+
+/*
+ *  call-seq:
+ *     int.anybits?(mask)  ->  true or false
+ *
+ *  Returns +true+ if any bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_anybits_p(VALUE num, VALUE mask)
+{
+    return num_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue;
+}
+
+/*
+ *  call-seq:
+ *     int.nobits?(mask)  ->  true or false
+ *
+ *  Returns +true+ if no bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_nobits_p(VALUE num, VALUE mask)
+{
+    return num_zero_p(rb_int_and(num, mask));
+}
+
 /*
  *  Document-method: Integer#succ
  *  Document-method: Integer#next
@@ -5396,6 +5435,9 @@ Init_Numeric(void)
     rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
     rb_define_method(rb_cInteger, "odd?", int_odd_p, 0);
     rb_define_method(rb_cInteger, "even?", int_even_p, 0);
+    rb_define_method(rb_cInteger, "allbits?", int_allbits_p, 1);
+    rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
+    rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
     rb_define_method(rb_cInteger, "upto", int_upto, 1);
     rb_define_method(rb_cInteger, "downto", int_downto, 1);
     rb_define_method(rb_cInteger, "times", int_dotimes, 0);
diff --git a/test/ruby/test_integer_comb.rb b/test/ruby/test_integer_comb.rb
index 80d08cac04..1ad13dd31b 100644
--- a/test/ruby/test_integer_comb.rb
+++ b/test/ruby/test_integer_comb.rb
@@ -457,6 +457,30 @@ def test_even_odd
     }
   end
 
+  def test_allbits_p
+    VS.each {|a|
+      VS.each {|b|
+        assert_equal((a & b) == b, a.allbits?(b), "(#{a}).allbits?(#{b}")
+      }
+    }
+  end
+
+  def test_anybits_p
+    VS.each {|a|
+      VS.each {|b|
+        assert_equal((a & b) != 0, a.anybits?(b), "(#{a}).anybits?(#{b}")
+      }
+    }
+  end
+
+  def test_nobits_p
+    VS.each {|a|
+      VS.each {|b|
+        assert_equal((a & b) == 0, a.nobits?(b), "(#{a}).nobits?(#{b}")
+      }
+    }
+  end
+
   def test_to_s
     2.upto(36) {|radix|
       VS.each {|a|
```

----------------------------------------
Feature #12753: Useful operator to check bit-flag is true or false
https://bugs.ruby-lang.org/issues/12753#change-68117

* Author: tagomoris (Satoshi TAGOMORI)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 2.5
----------------------------------------
Ruby's 0 is truthy value. It's useful for many cases, but it's confusing and I made many bugs when I'm writing code to handle binary data, because my thought is almost same with one to write C code in such situation.

```ruby
n = get_integer_value
if n & 0b10100000
  # code for the case when flag is true
else
  # never comes here :(
end
```

IMO it's very useful to have methods for such use-cases, like `#and?` and `#xor?` (`#or?` looks not so useful... I can't imagine the use case of this operator, but it's better to have for consistency).

```ruby
n = get_integer_value
case
when n.and?(0b10000000)
  # negative signed char
when n.and?(0b01110000)
  # large positive
else
  # small positive
end
```




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>