eval

The eval method provides a simple way of evaluating a Ruby expression in a string. At first sight, eval may appear to do the same job as the #{ } delimiters in a double-quoted string. These two lines of code produce identical results:

eval.rb

puts( eval("1 + 2" ) )    #=> 3
puts( "#{1 + 2}" )        #=> 3

Sometimes, however, the results may not be what you are expecting. Look at the following, for instance:

eval_string.rb

exp = gets().chomp()    #<= User enters 2*4
puts( eval( exp ))      #=> 8
puts( "#{exp}" )        #=> 2*4

Let’s suppose you enter 2 * 4, and this is assigned to exp. When you evaluate exp with eval, the result is 8, but when you evaluate exp in a double-quoted string, the result is "2*4". This is because anything read in by gets() is a string and "#{exp}" evaluates it as a string and not as an expression, whereas eval( exp ) evaluates a string as an expression. To force evaluation inside a string, you could place eval in the string (though that, admittedly, might defeat the object of the exercise):

puts( "#{eval(exp)}" )

Here is another example. Try it, and follow the instructions when prompted:

eval2.rb

print("Enter a string method name (e.g. reverse or upcase):")
                                   # user enters: upcase
methodname = gets().chomp()
exp2 = "'Hello world'."<< methodname
puts( eval( exp2 ) )               #=> HELLO WORLD
puts( "#{exp2}" )                  #=> 'Hello world'.upcase
puts( "#{eval(exp2)}" )            #=> HELLO WORLD

The eval method can evaluate strings spanning many lines, making it possible to execute an entire program embedded in a string:

eval3.rb

eval( 'def aMethod( x )
    return( x * 2 )
end

num = 100
puts( "This is the result of the calculation:" )
puts( aMethod( num ))' )

Look carefully at the previous code. It contains just one executable expression, which is a call to the eval() method. Everything else, which at first sight looks like code, is in fact a single-quoted string that is passed as an argument to eval(). The eval() method “unpacks” the contents of the string and turns it into real Ruby code that is then executed. This is displayed:

This is the result of the calculation:
200

With all this eval cleverness, let’s now see how easy it is to write a program that can itself write programs. Here it is:

eval4.rb

input = ""
until input == "q"
    input = gets().chomp()
    if input != "q" then eval( input ) end
end

This may not look like much, and yet this little program lets you both create and execute Ruby code from a prompt. Try it. Run the program, and enter the two methods shown here one line at a time (but don’t hitq to quit yet—you’ll be writing some more code in a moment):

def x(aStr); puts(aStr.upcase);end
def y(aStr); puts(aStr.reverse);end

Note that you have to enter each whole method on a single line since the program evaluates every line as it is entered. I’ll explain how to get around that limitation later. Thanks to eval, each method is turned into real, workable Ruby code. You can prove this by entering the following:

x("hello world")
y("hello world")

Now, when you press enter after each line in the previous code, the expressions are evaluated, and they call the two methods, x() and y(), which you wrote a moment ago, resulting in this output:

HELLO WORLD
dlrow olleh

That’s not bad for just five lines of code!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.131.255