ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT
@ 2012-07-21 18:20 naruse (Yui NARUSE)
  2012-07-22  2:03 ` [ruby-dev:45993] [ruby-trunk - Feature #6767] " duerst (Martin Dürst)
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: naruse (Yui NARUSE) @ 2012-07-21 18:20 UTC (permalink / raw
  To: ruby developers list


Issue #6767 has been reported by naruse (Yui NARUSE).

----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-dev:45993] [ruby-trunk - Feature #6767] Utility method to get a duplicated string whose encoding is ASCII-8BIT
  2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
@ 2012-07-22  2:03 ` duerst (Martin Dürst)
  2012-09-05  2:36 ` [ruby-dev:46113] " naruse (Yui NARUSE)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: duerst (Martin Dürst) @ 2012-07-22  2:03 UTC (permalink / raw
  To: ruby developers list


Issue #6767 has been updated by duerst (Martin Dürst).


naruse (Yui NARUSE) wrote:
> ある String を ASCII-8BIT にしたいことはしばしばあります。
> それだけならばまだ force_encoding しろよという話なのですが、
> #6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
> 毎行毎行 force_encoding を書いていくのにはつらいものがあります。
> 
> 解決案としては、
> (1) バイナリリテラルの導入

# encoding: UTF-8
の場合、\xAB とかが String リテラルに出てきたらその文字列を binary とみなすのは将来的にありかと思います。まだ UTF-8 以外のソースも結構ある間には早すぎるかと思います。

> (2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加

そもぞも force_encoding は force_encoding! にすべきでしたのではないかとなんか今反省したことがあります。
そうすると dup.force_encoding を force_encoding にできます。まあ、これでも大して短くならないけど。

> (3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
> が考えられます。

これはたった一つの演算にしか対応できないですよね。

> しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
> よって、(2) が妥当ではないかと思います。
> 
> 名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。

b はさすがに短すぎるのではないかと思います。せめて binary にしたらどうでしょうか。

本当に binary で操作したい場合にはいいです。しかし、「簡単にプログラムを書きたい」けど、色々の文字は全然考えてない、たまたま手元では動く、ということもありますので、あまり頭を使いたくない、または国際化をあまり意識しないプログラマでもできる限り分かりやすいようにした方がいいかと思います。
----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767#change-28271

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-dev:46113] [ruby-trunk - Feature #6767] Utility method to get a duplicated string whose encoding is ASCII-8BIT
  2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
  2012-07-22  2:03 ` [ruby-dev:45993] [ruby-trunk - Feature #6767] " duerst (Martin Dürst)
@ 2012-09-05  2:36 ` naruse (Yui NARUSE)
  2012-09-05  8:52 ` [ruby-dev:46118] " duerst (Martin Dürst)
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: naruse (Yui NARUSE) @ 2012-09-05  2:36 UTC (permalink / raw
  To: ruby developers list


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


duerst (Martin Dürst) wrote:
> naruse (Yui NARUSE) wrote:
> > 名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。
> 
> b はさすがに短すぎるのではないかと思います。せめて binary にしたらどうでしょうか。
> 
> 本当に binary で操作したい場合にはいいです。しかし、「簡単にプログラムを書きたい」けど、色々の文字は全然考えてない、たまたま手元では動く、ということもありますので、あまり頭を使いたくない、または国際化をあまり意識しないプログラマでもできる限り分かりやすいようにした方がいいかと思います。

binary だと binary を期待させすぎて良くないように思います。
また、リテラルくらい楽に書きたいという観点からしても .b の短さは合理的です。
名前空間の消費的にも、Stringなど組み込みクラスを継承して別のクラスを作るのは一般に危険な行為なので、
問題ないように思います。
これの使いやすさは個人的にはちょうど .irbrc にまったく同じ挙動をするメソッド追加していて、
かれこれ数年ほど便利に使ってたりします。
----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767#change-29182

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-dev:46118] [ruby-trunk - Feature #6767] Utility method to get a duplicated string whose encoding is ASCII-8BIT
  2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
  2012-07-22  2:03 ` [ruby-dev:45993] [ruby-trunk - Feature #6767] " duerst (Martin Dürst)
  2012-09-05  2:36 ` [ruby-dev:46113] " naruse (Yui NARUSE)
@ 2012-09-05  8:52 ` duerst (Martin Dürst)
  2012-09-05  9:59 ` [ruby-dev:46119] " naruse (Yui NARUSE)
  2012-11-05  7:24 ` [ruby-dev:46397] " matz (Yukihiro Matsumoto)
  4 siblings, 0 replies; 6+ messages in thread
From: duerst (Martin Dürst) @ 2012-09-05  8:52 UTC (permalink / raw
  To: ruby developers list


Issue #6767 has been updated by duerst (Martin Dürst).


naruse (Yui NARUSE) wrote:

> また、リテラルくらい楽に書きたいという観点からしても .b の短さは合理的です。

リテラルらしくはわからりますが、それでしたら思い切って本当のリテラルにした方がいいのではないかと思います。

成瀬さんには短くて便利で使っていただくのは全く問題ないですが、一般の方には「.b を付ければ問題が解決する」風潮 (ようするに、文字コードはわからないがとりあえず適当になにかやってしまう) を広げたくないです。

----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767#change-29188

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-dev:46119] [ruby-trunk - Feature #6767] Utility method to get a duplicated string whose encoding is ASCII-8BIT
  2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
                   ` (2 preceding siblings ...)
  2012-09-05  8:52 ` [ruby-dev:46118] " duerst (Martin Dürst)
@ 2012-09-05  9:59 ` naruse (Yui NARUSE)
  2012-11-05  7:24 ` [ruby-dev:46397] " matz (Yukihiro Matsumoto)
  4 siblings, 0 replies; 6+ messages in thread
From: naruse (Yui NARUSE) @ 2012-09-05  9:59 UTC (permalink / raw
  To: ruby developers list


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


duerst (Martin Dürst) wrote:
> naruse (Yui NARUSE) wrote:
> 
> > また、リテラルくらい楽に書きたいという観点からしても .b の短さは合理的です。
> 
> リテラルらしくはわからりますが、それでしたら思い切って本当のリテラルにした方がいいのではないかと思います。

リテラルだと文法が変わるので、過去のバージョンで読めなくなります。
一方、メソッドならば自分で定義すれば簡単に語感レイヤーを作ることができます。
これが「ハードルが高い」という意味です。

> 成瀬さんには短くて便利で使っていただくのは全く問題ないですが、一般の方には「.b を付ければ問題が解決する」風潮 (ようするに、文字コードはわからないがとりあえず適当になにかやってしまう) を広げたくないです。

そのような一般の人はおそらくRailsを用いるであろうところ、Railsなら通常.bをつけなくても問題ないですし、
問題が起きるような場所ではとりあえず.bをつけたからと言って問題は解決しないだろうので、
(たぶんforce_encoding("UTF-8")しない限り他の場所でエラーが上がるだけ)
そのようなことにはならないと思います。
----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767#change-29189

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-dev:46397] [ruby-trunk - Feature #6767] Utility method to get a duplicated string whose encoding is ASCII-8BIT
  2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
                   ` (3 preceding siblings ...)
  2012-09-05  9:59 ` [ruby-dev:46119] " naruse (Yui NARUSE)
@ 2012-11-05  7:24 ` matz (Yukihiro Matsumoto)
  4 siblings, 0 replies; 6+ messages in thread
From: matz (Yukihiro Matsumoto) @ 2012-11-05  7:24 UTC (permalink / raw
  To: ruby developers list


Issue #6767 has been updated by matz (Yukihiro Matsumoto).

Assignee changed from matz (Yukihiro Matsumoto) to naruse (Yui NARUSE)

OK to check in.

Matz.

----------------------------------------
Feature #6767: Utility method to get a duplicated string whose encoding is ASCII-8BIT
https://bugs.ruby-lang.org/issues/6767#change-32381

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: naruse (Yui NARUSE)
Category: core
Target version: 2.0.0


ある String を ASCII-8BIT にしたいことはしばしばあります。
それだけならばまだ force_encoding しろよという話なのですが、
#6361 の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、
毎行毎行 force_encoding を書いていくのにはつらいものがあります。

解決案としては、
(1) バイナリリテラルの導入
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding
が考えられます。

しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。
よって、(2) が妥当ではないかと思います。

名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。


diff --git a/string.c b/string.c
index d038835..76cbc36 100644
--- a/string.c
+++ b/string.c
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
 }
 
 static VALUE
-str_replace_shared(VALUE str2, VALUE str)
+str_replace_shared_without_enc(VALUE str2, VALUE str)
 {
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)
 	RSTRING(str2)->as.heap.aux.shared = str;
 	FL_SET(str2, ELTS_SHARED);
     }
-    rb_enc_cr_str_exact_copy(str2, str);
+    return str2;
+}
 
+static VALUE
+str_replace_shared(VALUE str2, VALUE str)
+{
+    str_replace_shared_without_enc(str2, str);
+    rb_enc_cr_str_exact_copy(str2, str);
     return str2;
 }
 
@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)
 
 /*
  *  call-seq:
+ *     str.b   -> str
+ *
+ *  Returns a copied string whose encoding is ASCII-8BIT.
+ */
+
+static VALUE
+rb_str_b(VALUE str)
+{
+    VALUE str2 = str_alloc(rb_cString);
+    str_replace_shared_without_enc(str2, str);
+    OBJ_INFECT(str2, str);
+    ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+    return str2;
+}
+
+/*
+ *  call-seq:
  *     str.valid_encoding?  -> true or false
  *
  *  Returns true for a string which encoded correctly.
@@ -7969,6 +7992,7 @@ Init_String(void)
 
     rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
     rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
+    rb_define_method(rb_cString, "b", rb_str_b, 0);
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index dfcaa94..3a4bca7 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase
       yield(*strs)
     end
   end
+
+  def test_str_b
+    s = "\u3042"
+    assert_equal(a("\xE3\x81\x82"), s.b)
+    assert_equal(Encoding::ASCII_8BIT, s.b.encoding)
+    s.taint
+    assert_equal(true, s.b.tainted?)
+    s.untrust
+    assert_equal(true, s.b.untrusted?)
+  end
 end


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-11-05  7:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-21 18:20 [ruby-dev:45992] [ruby-trunk - Feature #6767][Assigned] Utility method to get a duplicated string whose encoding is ASCII-8BIT naruse (Yui NARUSE)
2012-07-22  2:03 ` [ruby-dev:45993] [ruby-trunk - Feature #6767] " duerst (Martin Dürst)
2012-09-05  2:36 ` [ruby-dev:46113] " naruse (Yui NARUSE)
2012-09-05  8:52 ` [ruby-dev:46118] " duerst (Martin Dürst)
2012-09-05  9:59 ` [ruby-dev:46119] " naruse (Yui NARUSE)
2012-11-05  7:24 ` [ruby-dev:46397] " matz (Yukihiro Matsumoto)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).