Project

General

Profile

Actions

Feature #442

closed

name referencing in sprintf

Added by mame (Yusuke Endoh) over 15 years ago. Updated almost 13 years ago.


Description

=begin
遠藤です。

1.9 では正規表現で名前を使った参照ができるので、sprintf でも
名前を使った参照ができると便利じゃないでしょうか。

$ ./ruby -e 'puts "%d : %f" % { :foo => 1, :bar => 2 }'
1 : 2.000000

$ ./ruby -e 'printf("%d : %f\n", :foo => 1, :bar => 2)'
1 : 2.000000

あまりテストしていませんが、たたき台の実装です。

Index: sprintf.c

--- sprintf.c (revision 18638)
+++ sprintf.c (working copy)
@@ -103,18 +103,28 @@
} while (0)

#define GETARG() (nextvalue != Qundef ? nextvalue : \

  • posarg < 0 ? \
  • posarg == -1 ?
    (rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered",
    nextarg), 0) : \
  • posarg == -2 ? \
  • (rb_raise(rb_eArgError, "unnumbered(%d) mixed with named", nextarg), 0) :
    (posarg = nextarg++, GETNTHARG(posarg)))

#define GETPOSARG(n) (posarg > 0 ?
(rb_raise(rb_eArgError, "numbered(%d) after unnumbered(%d)", n,
posarg), 0) : \

  • posarg == -2 ? \
  • (rb_raise(rb_eArgError, "numbered(%d) after named", n), 0) :
    ((n < 1) ? (rb_raise(rb_eArgError, "invalid index - %d$", n), 0) :
    (posarg = -1, GETNTHARG(n))))

#define GETNTHARG(nth)
((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0)
: argv[nth])

+#define GETNAMEARG(id) (posarg > 0 ? \

  • (rb_raise(rb_eArgError, "named after unnumbered(%d)", posarg), 0) : \
  • posarg == -1 ? \
  • (rb_raise(rb_eArgError, "named after numbered"), 0) : \
  • rb_hash_aref(get_hash(&hash, argc, argv), id))

#define GETNUM(n, val)
for (; p < end && rb_enc_isdigit(*p, enc); p++) {
int next_n = 10 * n + (*p - '0');
@@ -141,7 +151,22 @@
val = NUM2INT(tmp);
} while (0)

+static VALUE
+get_hash(volatile VALUE *hash, int argc, const VALUE *argv)
+{

  • VALUE tmp;

  • if (*hash != Qundef) return *hash;

  • if (argc != 2) {

  • rb_raise(rb_eArgError, "one hash required");

  • }

  • tmp = rb_check_convert_type(argv[1], T_HASH, "Hash", "to_hash");

  • if (NIL_P(tmp)) {

  • rb_raise(rb_eArgError, "one hash required");

  • }

  • return (*hash = tmp);
    +}

/*

  • call-seq:
  • format(format_string [, arguments...] )   => string
    

@@ -412,6 +437,7 @@
VALUE nextvalue;
VALUE tmp;
VALUE str;

  • volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)
if ((f) & FWIDTH) {
@@ -513,6 +539,22 @@
flags |= FWIDTH;
goto retry;

  • case '<':
  •  {
    
  •  const char *start = p;
    
  •  ID id;
    
  •  for (; p < end && *p != '>'; ) {
    
  •      p += rb_enc_mbclen(p, end, enc);
    
  •  }
    
  •  if (p >= end) {
    
  •      rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
    
  •  }
    
  •  id = rb_intern3(start + 1, p - start - 1, enc);
    
  •  nextvalue = GETNAMEARG(ID2SYM(id));
    
  •  p++;
    
  •  goto retry;
    
  •  }
    
  • case '*':
    CHECK_FOR_WIDTH(flags);
    flags |= FWIDTH;

--
Yusuke ENDOH
=end


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #3574: Missing documentation for sprintf named argument supportClosed07/15/2010Actions
Actions #1

Updated by Tietew (Toru Iwase) over 15 years ago

=begin

On Fri, 15 Aug 2008 13:08:12 +0900
In article
[[ruby-dev:35851] [Feature:1.9] name referencing in sprintf]
"Yusuke ENDOH" wrote:

1.9 では正規表現で名前を使った参照ができるので、sprintf でも
名前を使った参照ができると便利じゃないでしょうか。

$ ./ruby -e 'puts "%d : %f" % { :foo => 1, :bar => 2 }'

Ruby-GetText で %{foo} というのを使っているので、合わせてあると嬉しい人
が多いかと。書式指定はできないのですが。

{} は書式指定無し版、<> は有り版 にするとか?

--
Tietew
Blog: http://www.tietew.jp/
PGP: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA

=end

Actions #2

Updated by nobu (Nobuyoshi Nakada) over 15 years ago

=begin
なかだです。

At Fri, 15 Aug 2008 14:20:15 +0900,
Tietew wrote in [ruby-dev:35852]:

On Fri, 15 Aug 2008 13:08:12 +0900
In article
[[ruby-dev:35851] [Feature:1.9] name referencing in sprintf]
"Yusuke ENDOH" wrote:

1.9 では正規表現で名前を使った参照ができるので、sprintf でも
名前を使った参照ができると便利じゃないでしょうか。

$ ./ruby -e 'puts "%d : %f" % { :foo => 1, :bar => 2 }'

[ruby-dev:16351]ではPythonと同じく %(foo)d としていました。

Ruby-GetText で %{foo} というのを使っているので、合わせてあると嬉しい人
が多いかと。書式指定はできないのですが。

{} は書式指定無し版、<> は有り版 にするとか?

Ruby-GetTextの実装を確認していないのですが、%{}以外のものがあっ
ても大丈夫なのでしょうか。

--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦

=end

Actions #3

Updated by Tietew (Toru Iwase) over 15 years ago

=begin

On Fri, 15 Aug 2008 16:28:56 +0900
In article
[[ruby-dev:35853] Re: [Feature:1.9] name referencing in sprintf]
Nobuyoshi Nakada wrote:

Ruby-GetText で %{foo} というのを使っているので、合わせてあると嬉しい人
が多いかと。書式指定はできないのですが。

{} は書式指定無し版、<> は有り版 にするとか?

Ruby-GetTextの実装を確認していないのですが、%{}以外のものがあっ
ても大丈夫なのでしょうか。

Ruby-GetText は String#% だけを書き換えていて、右辺が Hash だったら %{...}
を置換し、さもなければ元のものを呼んでいます。

こういうふうになります:
"%d %{foo}" % { :foo => 'bar' } # => "%d bar"
"%d %{foo}" % 123 # => "123 %{foo}"

--
Tietew
Blog: http://www.tietew.jp/
PGP: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA

=end

Actions #4

Updated by znz (Kazuhiro NISHIYAMA) over 15 years ago

=begin
西山和広です。

At Fri, 15 Aug 2008 13:08:12 +0900,
Yusuke ENDOH wrote:

1.9 では正規表現で名前を使った参照ができるので、sprintf でも
名前を使った参照ができると便利じゃないでしょうか。

$ ./ruby -e 'puts "%d : %f" % { :foo => 1, :bar => 2 }'
1 : 2.000000

$ ./ruby -e 'printf("%d : %f\n", :foo => 1, :bar => 2)'
1 : 2.000000

あまりテストしていませんが、たたき台の実装です。

正規表現の例を出すのなら、Hash限定ではなく[]メソッドを呼んだ方が
便利なのではないでしょうか。

--
|ZnZ(ゼット エヌ ゼット)
|西山和広(Kazuhiro NISHIYAMA)

=end

Actions #5

Updated by ko1 (Koichi Sasada) over 15 years ago

  • Assignee set to matz (Yukihiro Matsumoto)

=begin

=end

Actions #6

Updated by yugui (Yuki Sonoda) over 15 years ago

  • Target version set to 1.9.1 Release Candidate

=begin

=end

Actions #7

Updated by matz (Yukihiro Matsumoto) over 15 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r19641.
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0