Elegant way to rename a file with an user-supplied expression?

Hi.

I’m creating a small Ruby program to do some chores that I used to do
with
different programs coupled together and shell scripts. I’m doing it
mostly to
learn more Ruby (I’m still a beginner), so if in the end I have to
invoke a
foreign program in another process, I will, but I want to at least try
other
possibilites.

I want to rename a file, and I would like to let the user supply the way
to do
the rename as a string. There is a “rename” program that comes with Perl
(at
least on some Linux distributions), and that is exactly like I would
want to
do. The program is just 40 lines (http://pastie.org/9625733) and it
simply
calls eval on the user-supplied string:

Change from YYYYMMDD to YYYY-MM-DD

rename ‘s|(\d\d\d\d)(\d\d)(\d\d)|$1-$2-$3|’ *.foo

How would you do something like that? I can use eval too, but I don’t
really
understand the second parameter, and documentation is scarce about eval.
With
Perl here the eval()ed code is applied to the $_ automatic variable, so
is
convenient. I don’t know how to do such thing conveniently with Ruby.

I also though on how to do not just any expression, which is cool, but
unnecessary since 99% of the times a simple call to gsub would do fine.
On that
vein, is there an elegant way to do what the example above? That is,
supply
one string that contains both the match and the substitution. I
understand it
as both Ruby and Perl having /regexp/ built into the language, but Perl
even
having s/// as “first class” language construct.

To summarize:

  1. How would you use eval to apply an user supplied string to transform
    a
    single variable?
  2. Is there a succint way to perform a substitution on a string like
    sed/Perl
    do?

Thank you very much.

On Oct 6, 2014, at 12:50, Alejandro E. [email protected] wrote:

documentation is scarce about eval

% ri Kernel.eval
= Kernel.eval

(from ruby core)

eval(string [, binding [, filename [,lineno]]]) → obj


Evaluates the Ruby expression(s) in string. If
binding is given, which must be a Binding object, the evaluation
is performed in its context. If the optional filename and
lineno parameters are present, they will be used when reporting
syntax errors.

def get_binding(str)
return binding
end
str = “hello”
eval “str + ’ Fred’” #=> “hello Fred”
eval “str + ’ Fred’”, get_binding(“bye”) #=> “bye Fred”

On Mon, Oct 6, 2014 at 9:50 PM, Alejandro E. [email protected] wrote:

least on some Linux distributions), and that is exactly like I would want to

single variable?
2. Is there a succint way to perform a substitution on a string like sed/Perl
do?

The gsub part is easy enough:

2.0.0p195 :015 > s = “12345678”
=> “12345678”
2.0.0p195 :016 > r = “(\d\d\d\d)(\d\d)(\d\d)”
=> “(\d\d\d\d)(\d\d)(\d\d)”
2.0.0p195 :017 > p = “\1-\2-\3”
=> “\1-\2-\3”
2.0.0p195 :018 > s.gsub(re,p)
=> “1234-56-78”

The syntax is a bit different since the gsub replacement syntax is
different from perl’s, but the idea is the same.

Jesus.

El Monday 06 October 2014, Ryan D. escribi:

On Oct 6, 2014, at 12:50, Alejandro E. [email protected] wrote:

documentation is scarce about eval

% ri Kernel.eval

That’s exactly what I meant. That documentation points to Binding, which
in
turn points to binding(). Is not necessarily an easy concepto to grasp,
specially if you are still beginning. I called that scarce. Maybe hard
was a
better word, but I searched for non-trivial examples online I didn’t
found, so
that was my feeling.

El Wednesday 08 October 2014, Jesús Gabriel y Galán escribió:

The gsub part is easy enough:
(…)
The syntax is a bit different since the gsub replacement syntax is
different from perl’s, but the idea is the same.

That’s what I said, and is fine of course. I just wondered wheter it
existed
another way to do it with one string only (the CLI interface was getting
complicated already). The most likely answer was “no” of course, but
given
that the language has a first class regular expression, it might have a
substitution, too (like Perl or sed).