Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what does this backtick ruby code mean?

Tags:

regex

ruby

while line = gets
   next if line =~ /^\s*#/    # skip comments
   break if line =~ /^END/   # stop at end

   #substitute stuff in backticks and try again
   redo if line.gsub!(/`(.*?)`/) { eval($1) } 

end

What I don't understand is this line:

line.gsub!(/`(.*?)`/) { eval($1) }
  1. What does the gsub! exactly do?
  2. the meaning of regex (.*?)
  3. the meaning of the block {eval($1)}
like image 309
Steve Zhang Avatar asked Dec 17 '25 23:12

Steve Zhang


2 Answers

  1. It will substitute within the matched part of line, the result of the block.
  2. It will match 0 or more of the previous subexpression (which was '.', match any one char). The ? modifies the .* RE so that it matches no more than is necessary to continue matching subsequent RE elements. This is called "non-greedy". Without the ?, the .* might also match the second backtick, depending on the rest of the line, and then the expression as a whole might fail.
  3. The block returns the result of eval ("evaluate a Ruby expression") on the backreference, which is the part of the string between the back tick characters. This is specified by $1, which refers to the first paren-enclosed section ("backreference") of the RE.

In the big picture, the result of all this is that lines containing backtick-bracketed expressions have the part within the backticks (and the backticks) replaced with the result value of executing the contained Ruby expression. And since the outer block is subject to a redo, the loop will immediately repeat without rerunning the while condition. This means that the resulting expression is also subject to a backtick evaluation.

like image 127
DigitalRoss Avatar answered Dec 20 '25 18:12

DigitalRoss


Replaces everything between backticks in line with the result of evaluating the ruby code contained therein.

>> line = "one plus two equals `1+2`"
>> line.gsub!(/`(.*?)`/) { eval($1) }
>> p line
=> "one plus two equals 3"

.* matches zero or more characters, ? makes it non-greedy (i.e., it will take the shortest match rather than the longest).

$1 is the string which matched the stuff between the (). In the above example, $1 would have been set to "1+2". eval evaluates the string as ruby code.

like image 26
nornagon Avatar answered Dec 20 '25 17:12

nornagon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!