Ask a Question related to Ruby, Design and Development.
-
Florian Gross #1
Bug when rerouting String#gsub with a block using $1?
Moin!
This code:
class String
alias :old_gsub :gsub
def gsub(*args, &block)
old_gsub(*args, &block)
end
end
"hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
produces this output for me:
nilnil
(I'm using ruby 1.8.0 (2003-08-04) [i386-mswin32] and I'm told that it
does the same in the 1.8.0 final, 1.7.3 and 1.6.8 on Linux.)
Is this behaviour by design or is this a bug? If it's not a bug: Why
is $1 changed to nil in this case?
(This behaviour is causing an annoying bug in my new Ruby
implementation of Perl 6's Junctions and thus effectively replacing
irb's prompt with "()::>")
Thanks for any answers and effort to clarify this issue!
Regards,
Florian Gross
Florian Gross Guest
-
behaviour change of String#gsub(pattern) {|m| ... } for ruby 1.9/ruby2?
String#gsub(pattern) {|m| ... } It really would be nice to get match data in 'm', but this would surely break _a lot_ of scripts. How about... -
behaviour change of String#gsub(pattern) {|m| ... } for ruby1.9/ruby2?
Hi -- On Fri, 21 Nov 2003, Florian Gross wrote: I've also just noticed this: irb(main):001:0> "abc".gsub(/((x?)abc)/) {|n,m| p n, m}... -
gsub(/\s*$/, "") doubling string
Hello, I recently downloaded ruby 1.8.0 p3, (2003-06-23) , and tried it on some code that chopped trailing spaces from a string using gsub(/\s*$/,... -
Difference in module_eval taking block vs. taking string (1.8 bug?)
The following code: class Klass end p Klass.instance_methods(false) Klass.module_eval do def hello puts 'hello' end end -
find physical blocks/disks, mapped from Oracle file# and block#, block corruption
Hello "lopera" <prlopera@techie.com> schrieb im Newsbeitrag news:3E1C7C00.9090402@techie.com... I think that we need a bit more data here.... -
Mauricio Fernández #2
Re: Bug when rerouting String#gsub with a block using $1?
On Mon, Aug 18, 2003 at 07:38:52AM +0900, Florian Gross wrote:
It seems it is by design:> Moin!
>
> This code:
>
> class String
> alias :old_gsub :gsub
> def gsub(*args, &block)
> old_gsub(*args, &block)
> end
> end
>
> "hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
>
> produces this output for me:
>
> nilnil
>
> (I'm using ruby 1.8.0 (2003-08-04) [i386-mswin32] and I'm told that it
> does the same in the 1.8.0 final, 1.7.3 and 1.6.8 on Linux.)
>
> Is this behaviour by design or is this a bug? If it's not a bug: Why
> is $1 changed to nil in this case?
batsman@tux-chan:/tmp$ expand -t2 a.rb
def foo
puts "Match: #{$1.inspect}"
end
"abcd" =~ /(b)/
foo
puts "Match: #{$1.inspect}"
batsman@tux-chan:/tmp$ ruby a.rb
Match: nil
Match: "b"
So $1 is method-scoped.
Now, is there any way to propagate $1??
We need it if gsub and friends are to be wrapped transparently.
--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
One tree to rule them all,
One tree to find them,
One tree to bring them all,
and to itself bind them.
-- Gavin Koch <gavin@cygnus.com>
Mauricio Fernández Guest
-
Mauricio Fernández #3
Re: Bug when rerouting String#gsub with a block using $1?
On Mon, Aug 18, 2003 at 02:43:00PM +0900, Yukihiro Matsumoto wrote:
But this doesn't solve the problem, does it?> |Now, is there any way to propagate $1??
> |We need it if gsub and friends are to be wrapped transparently.
>
> Explicitly? You can pass the match data and assign it to $~.
I don't see how $~ would help in
class String
alias :old_gsub :gsub
def gsub(*args, &block)
old_gsub(*args, &block)
end
end
"hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
Is this just impossible to do in Ruby?
At any rate the behavior of the block is quite strange w.r.t. the binding
of $1. It is very different from that of other variables/globals in the
closure: $1 references the $1 in gsub, instead of the one in old_gsub
or the outer one.
However
batsman@tux-chan:/tmp$ expand -t2 b.rb
def foo
"foo" =~ /(foo)/
yield
end
def bar
"bar" =~ /(bar)/
foo { puts "foo: " + $1.inspect }
yield
end
bar {puts "bar: " + $1.inspect}
puts "1 world".gsub(/(1)/) { $1 + " is one" }
batsman@tux-chan:/tmp$ ruby b.rb
foo: "bar"
bar: nil
1 is one world
So gsub is indeed one special case in that $1 is bound to the "inner $1"
instead of the outer. And there's AFAIK no way to wrap gsub without
breaking it because of that.
--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Turn right here. No! NO! The OTHER right!
Mauricio Fernández Guest
-
Yukihiro Matsumoto #4
Re: Bug when rerouting String#gsub with a block using $1?
Hi,
In message "Re: Bug when rerouting String#gsub with a block using $1?"
on 03/08/18, Mauricio Fernández <batsman.geo@yahoo.com> writes:
| "hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
|
|Is this just impossible to do in Ruby?
In pure Ruby, yes.
Ah, wait. If you don't need thread safety, you can do it as:
"hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
class String
alias :old_gsub :gsub
def gsub(*args, &block)
if block
old_gsub(*args) {
$match = $~
eval("$~ = $match", block) # the trick here.
yield $&
}
else
old_gsub(*args, &block)
end
end
end
"hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
matz.
Yukihiro Matsumoto Guest
-
Mauricio Fernández #5
Re: Bug when rerouting String#gsub with a block using $1?
On Mon, Aug 18, 2003 at 04:47:47PM +0900, Yukihiro Matsumoto wrote:
ouch. We'll then need C to make real Junctions then (not so bad since> Hi,
>
> In message "Re: Bug when rerouting String#gsub with a block using $1?"
> on 03/08/18, Mauricio Fernández <batsman.geo@yahoo.com> writes:
>
> | "hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
> |
> |Is this just impossible to do in Ruby?
>
> In pure Ruby, yes.
we'd do it anyway for speed).
Thank you for your quick responses.> Ah, wait. If you don't need thread safety, you can do it as:
--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Steal my cash, car and TV - but leave the computer!
-- Soenke Lange <soenke@escher.north.de>
Mauricio Fernández Guest
-
Dan Doel #6
Re: Bug when rerouting String#gsub with a block using $1?
What about:
p "hello world".gsub(/(\w+)/) { puts $1; $1 }
puts
class String
alias :old_gsub :gsub
def gsub(*args, &block)
if block
pattern = args[0]
old_gsub(pattern) { |match|
eval "#{pattern.inspect} =~ \"#{match}\"", block
yield match
}
else
old_gsub(*args, &block)
end
end
end
p "hello world".gsub(/(\w+)/) { puts $1; $1 }
Or does this miss something that gsub does?
- Dan
Dan Doel Guest
-
nobu.nokada@softhome.net #7
Re: Bug when rerouting String#gsub with a block using $1?
Hi,
At Mon, 18 Aug 2003 16:47:47 +0900,
Yukihiro Matsumoto wrote:You forget the trick that you'd written ago.> Ah, wait. If you don't need thread safety, you can do it as:
eval("proc{|m|$~ = m}", block).call($~)> "hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
> class String
> alias :old_gsub :gsub
> def gsub(*args, &block)
> if block
> old_gsub(*args) {--> yield $&
> }
> else
> old_gsub(*args, &block)
> end
> end
> end
> "hello world".gsub(/(\w+)/) { print $1; $1 }; print "\n"
Nobu Nakada
nobu.nokada@softhome.net Guest
-
Florian Gross #8
Re: Bug when rerouting String#gsub with a block using $1?
Yukihiro Matsumoto wrote:
Moin!> Hi,
That's a nice hack, thank you! And I think Nobu Nakada's change even> In message "Re: Bug when rerouting String#gsub with a block using $1?"
> on 03/08/18, Mauricio Fernández <batsman.geo@yahoo.com> writes:
>
> |Is this just impossible to do in Ruby?
>
> In pure Ruby, yes.
>
> Ah, wait. If you don't need thread safety, you can do it as:
>
> [code snippet snipped]
makes it thread-safe, but are you sure that the incosistent behavior
of $1 in blocks passed to gsub is needed? IMHO this is a confusing
trap and thus a source of unnecessary debugging sessions for users.
That aside: Are there other methods like sub, sub!, gsub and gsub!
which have this special behavior?
Regards and thank you for designing a wonderful language,> matz.
Florian Gross
Florian Gross Guest
-
Yukihiro Matsumoto #9
Re: Bug when rerouting String#gsub with a block using $1?
Hi,
In message "Re: Bug when rerouting String#gsub with a block using $1?"
on 03/08/18, Florian Gross <flgr@ccan.de> writes:
|That's a nice hack, thank you! And I think Nobu Nakada's change even
|makes it thread-safe, but are you sure that the incosistent behavior
|of $1 in blocks passed to gsub is needed? IMHO this is a confusing
|trap and thus a source of unnecessary debugging sessions for users.
Then don't use ugly dollar variables. But perhaps gsub should have
passed the match data to the block for convenience.
|That aside: Are there other methods like sub, sub!, gsub and gsub!
|which have this special behavior?
"gets" modifies $_ in local scope. $_ and $~ (and $1 etc) are treated
specially.
matz.
Yukihiro Matsumoto Guest



Reply With Quote

