Finally, let’s return to the program you looked at earlier: eval4.rb. This, you may recall, prompts the user to enter strings to define code at runtime, evaluates those strings, and creates new runnable methods from them.
One drawback of that program was that it insists that each method be entered on a single line. It is, in fact, pretty simple to write a program that allows the user to enter methods spanning many lines. Here, for example, is a program that evaluates all the code entered up until a blank line is entered:
writeprog.rb
program = "" input = "" line = "" until line.strip() == "q" print( "?- " ) line = gets() case( line.strip() ) when '' puts( "Evaluating..." ) eval( input ) program += input input = "" when '1' puts( "Program Listing..." ) puts( program ) else input += line end end
You can try this by entering whole methods followed by blank lines, like this (just enter the code, of course, not the comments):
def a(s) # <= press Enter after each line return s.reverse # <= press enter (and so on...) end # <- Enter a blank line here to eval these two methods def b(s) return a(s).upcase end # <- Enter a blank line here to eval these two methods puts( a("hello" ) ) # <- Enter a blank line to eval #=> olleh puts( b("goodbye" ) ) # <- Enter a blank line to eval #=> EYBDOOG
After each line entered, a prompt (?-
) appears except when the program is in the process of evaluating code, in which case it displays “Evaluating,” or when it shows the result of an evaluation, such as olleh
.
If you enter the text exactly as indicated earlier, this is what you should see:
Write a program interactively. Enter a blank line to evaluate. Enter 'q' to quit. ?- def a(s) ?- return s.reverse ?- end ?- Evaluating... ?- def b(s) ?- return a(s).upcase ?- end ?- Evaluating... ?- puts(a("hello")) ?- Evaluating... olleh ?- b("goodbye") ?- Evaluating... EYBDOOG
This program is still very simple. It doesn’t even have any basic error recovery let alone fancy stuff such as file saving and loading. Even so, this small example demonstrates just how easy it is to write self-modifying programs in Ruby.
18.118.226.66