Feature #11997

A method to read a file with interpolations

Added by sawa (Tsuyoshi Sawada) about 1 year ago. Updated about 1 year ago.

Target version:


I request a single method that reads a file while interpreting interpolated Ruby code in it (in the current context). For example, suppose I have a file foo.txt.


#{char * 20}
Hello, my name is #{name}.
#{char * 20}

I am not sure about what method name the proposed feature should have, and on which class it should be defined, but let's temporarily call it File.eval. Then I would like to do:

char = "*"
name = "John Doe"
File.eval("foo.txt") # => "********************\nHello, my name is John Doe.\n********************\n"

The use case that I have in mind is to easily create template engines/preprocessors, or do an equivalent of what such software do on the fly within a script. There are tools like erb, SCSS, haml, etc., but those force a particular syntax, and they are full fledged software with their own parsing capability, which means it takes an extra time to parse, and the sortware may have their own bugs. I often feel that I do not want to adopt any of the syntax forced in those limited choice of template/preprocessing software, but do it in a freer way.

Using what we have currently, I can do it with:

eval('"' +"foo.txt") + '"')

but that looks cumbersome, and wish if Ruby had a C-level built-in capability for doing that. I believe that would encourage wide range of Ruby users to more freely create their own templating system.


#1 [ruby-core:72885] Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Status changed from Open to Feedback

Why not erb?

#2 [ruby-core:72886] Updated by sawa (Tsuyoshi Sawada) about 1 year ago

Why not erb?

Erb syntax is too much noise to me. It is centered toward html (it resembles html tagging), which is notorious for being a human-unfriendly notation. And it does not look that good when used for things other than an html file. I never felt comfortable with it. Ruby's interpolation syntax #{} is simple, and does not require learning additional things, once you know Ruby.

#3 [ruby-core:74252] Updated by justcolin (Colin Fulton) about 1 year ago

I agree that ERB is ugly for a lot of cases, but—since there is a one liner to write this in Ruby—I don't think it needs to be added to the core language.

EDIT: After thinking about this for a while longer, I think this would be a nice thing to add. It should be very easy to implement in core and would provide a templating syntax that looks a lot more Ruby-ish than ERB.

#4 [ruby-core:74254] Updated by justcolin (Colin Fulton) about 1 year ago

As far as implementation, File.eval doesn't feel right since you may want any IO object—or any object with #read—to be eval-able. Also giving File the ability to do eval feels like it violates the single responsibility principle a bit too much. Instead maybe #eval or #instance_eval/#instance_exec/#class_eval/etc. should accept instances of IO or IO-like objects as an argument. Calls would then look something like:


#5 [ruby-core:74406] Updated by shyouhei (Shyouhei Urabe) about 1 year ago

This is difficult to implement in-core than it sounds. String interpolation is tightly built into our parser; hard to extirpate. A built-in for this feature would accordingly result in the same eval + maneuver, to just translate into C.

#6 [ruby-core:74421] Updated by mame (Yusuke Endoh) about 1 year ago

-1. I don't think that this is suitable as a core feature. We should leave such a thing to a library like erb.

Also available in: Atom PDF