Regex global variables not set

I came across something that seemed unusual, and I was wondering if anyone could explain why.

1.8.7 :001 > some_str = "Hello World"
 => "Hello World" 
1.8.7 :002 > some_str.try(:match, /^(\w*)/)
 => #<MatchData "Hello" 1:"Hello"> 
1.8.7 :003 > $1
 => nil 
1.8.7 :004 > some_str.match(/^(\w*)/)
 => #<MatchData "Hello" 1:"Hello"> 
1.8.7 :005 > $1
 => "Hello" 

I'm not sure why the global variable is $1not set the first time, but set the second. Any ideas?

+5
source share
2 answers

Let me show you how it is implemented try. If you want to see it yourself, look at the source of activesupport. It is defined in /lib/active_support/core_ext/object/try.rb

class Object
  def try(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      public_send(*a, &b)
    end
  end
end

What this basically does is simply send the method name and full arguments to Object. public_sendmatches sending, but can only be used to call public methods.

, , :

class Object
  def try(*a)
    result = public_send(*a)
    puts $1.inspect
    result
  end
end

string = "Hello"
string.try(:match, /^(\w*)/)
puts $1.inspect

"Hello"
nil

: ​​ ruby?. . , . , (. .)

[...], $_ $~ . , , , .

, , $1 , :

1.9.3-p194 :001 > global_variables
 => [:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE, :$-K,
     :$,, :$/, :$-0, :$\, :$_, :$stdin, :$stdout, :$stderr, :$>, :$<, :$.,
     :$FILENAME, :$-i, :$*, :$?, :$$, :$:, :$-I, :$LOAD_PATH, :$",
     :$LOADED_FEATURES, :$VERBOSE, :$-v, :$-w, :$-W, :$DEBUG, :$-d, :$0,
     :$PROGRAM_NAME, :$-p, :$-l, :$-a, :$binding, :$1, :$2, :$3, :$4, :$5, :$6,
     :$7, :$8, :$9] 

, Ruby Bug Tracker. . Ruby Bug # 6723

+3

try

def try(method, *args, &block)
  send(method, *args, &block)
end

, , nil, nil. ? regexp : ( , , ). match try, try, .

def do_match string, regexp
  string =~ regexp
  $1
end
do_match "Hello World", /^(\w*)/ #=> returns 'Hello'
$1 #=> returns nil 
+3

All Articles