Shell, ruby and regexp

over Mac OS X the latest and ruby 1.8.4 i’ve found strange interferences
between the shell (in my case zsh) and arguments to a ruby script if one
of the args is a Regexp as for examples :

/to./ - case 1
/^Tit.
/ - case 2

  • case 1 (not the most seriaus) gave an answer from zsh BEFORE any
    answer of my ruby script :

~/Desktop%> ruby test_args.rb /to./
zsh: no matches found: /to.
/

  • case 2 seems to be DANGEROUS because it gaves me a kot of unexepected
    args :

~/Desktop%> ruby test_args.rb /^Tit.*/
/Applications/
/Developer/
/Library/
/Network/
/System/
/Users/
/Volumes/
/automount/
/bin/
/cores/
/dev/
/etc/
/opt/
/private/
/sbin/
/tmp/
/usr/
/var/

Notice i’ve discovered that when designing a small script in order to
delete files )))

Obviously i’ve found a workaround using quotes around the regexp :

~/Desktop%> ruby test_args.rb “to.*”

but in that case i need another arg to my script in order to tell ruby
it is a regular expression.

did someone have the same quirk ?

Une bévue wrote:

~/Desktop%> ruby test_args.rb /to./
zsh: no matches found: /to.
/

This is a classic error in the use of a shell. You need to understand
that
your typing is interpreted first by the shell, and only then by Ruby.

/Users/
/usr/
but in that case i need another arg to my script in order to tell ruby
it is a regular expression.

What’s wrong with the original string enclosed in quotes?

Instead of:

ruby test_args.rb /to.*/

Type this instead:

ruby test_args.rb “/to.*/”

did someone have the same quirk ?

I need to tell you something. Everyone who uses any variation on Unix
(Unix,
Linux, etc.) learns this right away about shell sessions.

The solution is to get into the habit of using “irb” for little
experiments,
and writing a formal scripts for big experiments. Avoid typing things
into
the shell that it will interpret as wildcards.

Paul L. [email protected] wrote:

What’s wrong with the original string enclosed in quotes?

Instead of:

ruby test_args.rb /to.*/

Type this instead:

ruby test_args.rb “/to.*/”

ok i’ve done THE MISTAKE to rememeber zsh as a priority over ruby )))

my answer to “What’s wrong with the original string enclosed in quotes?”

that didn’t work, my script sees it as a string and even if (for this
arg and if enclosed with //) :

this_arg=Regexp.new(this_arg)

then if this arg = “/to.*/”

i get :

puts this_arg.source # (after Regexp.new)

=> /to./ INSTEAD OF to.

the reason why i make no use of // for a regexp arg then i’m obliged to
have another arg yelling if this arg is or not a regexp.

may be here i’ve missed something too…

MonkeeSage [email protected] wrote:

this_arg=Regexp.new(this_arg[1…-2])

clever idae, thanks again !!!

Une bévue wrote:

=> /to./ INSTEAD OF to.

this_arg=Regexp.new(this_arg[1…-2])

Regards,
Jordan

On 2006.10.03 16:05, Une b?vue wrote:

ruby test_args.rb “/to.*/”

ok i’ve done THE MISTAKE to rememeber zsh as a priority over ruby )))

my answer to “What’s wrong with the original string enclosed in quotes?”

that didn’t work, my script sees it as a string and even if (for this
arg and if enclosed with //) :

Everything you get in ARGV is a String. You cannot create Ruby
objects outside Ruby.

this_arg=Regexp.new(this_arg)

then if this arg = “/to.*/”

i get :

puts this_arg.source # (after Regexp.new)

=> /to./ INSTEAD OF to.

You have a few choices. You can pass in ‘/to./’ and strip off the /'s,
you can #eval it or you could pass in 'to.
’ instead and then
interpolate
or Regexp.new it.

On Tuesday 03 October 2006 16:05, Une bévue wrote:

i get :

puts this_arg.source # (after Regexp.new)

=> /to./ INSTEAD OF to.

Regexp.new(’/.rb/’[%r(/(.?)/), 1])

/.*rb/

“Une bévue” [email protected] wrote:

ok i’ve done THE MISTAKE to rememeber zsh as a priority over ruby )))

It’s not so much a “priority” as simple order of things happening (you
can
read that on each shell’s man page): first a command line undergoes
various
substitutions (these change between shells and syntax used in the
command
line), only then the result of these subsitutions is handed off to the
process forked (or shell internal command).

my answer to “What’s wrong with the original string enclosed in
quotes?”

that didn’t work, my script sees it as a string and even if (for this
arg and if enclosed with //) :

The point is, your script sees every argument as string. There is no
other type of arguments for process execs. If you need conversion, you
have
to do it yourself. For example

ARGV.map! do |arg|
case arg
when %r{\A/./[io]\z}
eval arg
when %r{[±]?\d+}
arg.to_i
else
arg
end
end

may be here i’ve missed something too…

I guess you were mindset that there needs to be some mechanism to
automatically convert process arguments for you. That does not exist -
at
least not in Ruby.

Kind regards

robert

I guess you were mindset that there needs to be some mechanism to
automatically convert process arguments for you. That does not exist - at
least not in Ruby.

I’m not sure there’s any way to write a library that would get it right
all
of the time. In fact, it would almost certainly screw it up more often
than
not.

Best to do it yourself.

Martin

Robert K. [email protected] wrote:

end

may be here i’ve missed something too…

I guess you were mindset that there needs to be some mechanism to
automatically convert process arguments for you.

not exactly because i was doing a :

arg = Regex.new(arg)…