From: Trans Date: 2008-03-02T23:15:49+09:00 Subject: Re: Named sprintf parameters On Feb 28, 7:13 pm, ara howard wrote: > On Feb 28, 2008, at 1:09 PM, yermej wrote: > > > > > On Feb 28, 11:29 am, ara howard wrote: > > >> class String > >> module M > >> def % *args > >> newstuff > >> super > >> end > >> end > >> include M > >> end > > > Can you please explain this? It looks to me like it would allow you to > > override a method, but still call the original without using alias. > > However, when I try anything like that, it only calls the original > > method. The method defined inside of M isn't called. Is that a 1.9 > > thing or am I misunderstanding what you meant? > > i was just being stupid. you'd need something like this > > cfp2:~ > cat a.rb > class String > > Percent = instance_method '%' unless defined? Percent > > def % *a, &b > a.flatten! > string = > case a.last > when Hash > expand a.pop > else > self > end > if a.empty? > string > else > Percent.bind(string).call(*a, &b) > end > end > > def expand! vars = {} > loop do > changed = false > vars.each do |var, value| > var = var.to_s > var.gsub! %r/[^a-zA-Z0-9_]/, '' > [ > %r/\$#{ var }\b/, > %r/\@#{ var }\b/, > %r/\$\{\s*#{ var }\s*\}/, > %r/\@\{\s*#{ var }\s*\}/, > ].each do |pat| > changed = gsub! pat, "#{ value }" > end > end > break unless changed > end > self > end > > def expand opts = {} > dup.expand! opts > end > > end > > puts( 'I am @name'.expand(:name => 'Ara') ) > puts( 'I am @name' % {:name => 'Ara'} ) > > cfp2:~ > ruby a.rb > I am Ara > I am Ara Hmmm... this looks more like an answer to the interpolation question asked in a earlier thread. Is this a full-fledge implementation? Would it be a better solution then: def String.interpolate(&str) eval "%{#{str.call}}", str.binding end T.