Faster alternative to eval? - performance

I'm dealing with a web app that uses a home-grown templating system that lets Perl code be embedded in HTML. These statements are executed by the template parser at run-time using eval EXPR.
This is very flexible, but these statements are scattered everywhere, and get executed a lot. eval EXPR (as opposed to eval BLOCK) requires Perl to fire up the interpreter each time, and my profiling reveals that they're a reasonably significant source of slowdown.
Many of the embedded Perl statements are very simple. For example, a template might have a line like this:
<p>Welcome, <!--E: $user->query('name') -->.
Or:
<p>Ticket number <!--E: $user->generate_ticket_number() --> has been generated.
That is, they're just calling object methods. There are more complicated ones, too, though.
I'm hoping to optimize this, and so far have two ideas, both of which are terrible. The first is to rewrite all templates to replace simple calls with tokens like USER:NAME and USER:GENERATETICKETNUMBER, which the parser could then scan for and invoke the appropriate object method. But then instead of dealing with templates that mix HTML and Perl, I would have templates that mix HTML, Perl, and tokens.
The second idea is to try to parse the embedded Perl, figure out what the statement wants to do, and, if it's simple enough, call the appropriate object method via a symbolic reference. This is obviously insane.
Is there some logical solution I'm overlooking?

Try taking an approach similar to the one that mod_perl uses to compile CGIs:
Convert the template into Perl code. For instance, your first example might convert to something like:
print "<p>Welcome, ";
print $user->query('name');
print ".\n";
Wrap a sub { ... } around that code, along with some code to unpack arguments (e.g, for things like $user in the sample).
eval that code. Note that it returns a coderef.
Call that coderef repeatedly. :)

You might take a look at Mojolicious. It has a templating engine which allow a syntax close to what you are using. You could possibly switch to use it or look at its source (click source on left of previous link) to see if you can draw some ideas.
FYI the Mojolcious templating engine's syntax allows the following forms intermixed with HTML appropriately
<% Perl code %>
<%= Perl expression, replaced with result %>
<%== Perl expression, replaced with XML escaped result %>
<%# Comment, useful for debugging %>
<%% Replaced with "<%", useful for generating templates %>
% Perl code line, treated as "<% line =%>"
%= Perl expression line, treated as "<%= line %>"
%== Perl expression line, treated as "<%== line %>"
%# Comment line, treated as "<%# line =%>"
%% Replaced with "%", useful for generating templates

You might want to look at the guts of Text::MicroTemplate. Realistically, you might want to use Text::MicroTemplate, as it likely fits your needs. It builds a subroutine that concatenates strings as needed, much like duskwuff suggested. Here's the result of build_mt('hello, <?= $_[0] ?>') in re.pl:
$CODE1 = sub {
package Devel::REPL::Plugin::Packages::DefaultScratchpad;
use warnings;
use strict 'refs';
local $SIG{'__WARN__'} = sub {
print STDERR $_mt->_error(shift(), 4, $_from);
}
;
Text::MicroTemplate::encoded_string(sub {
my $_mt = '';
local $_MTREF = \$_mt;
my $_from = '';
$_mt .= 'hello, ';
$_from = $_[0];
$_mt .= ref $_from eq 'Text::MicroTemplate::EncodedString' ? $$_from : do {
$_from =~ s/([&><"'])/$Text::MicroTemplate::_escape_table{$1};/eg;
$_from
};
return $_mt;
}
->(#_));
};

You should not be using 'eval' to call methods in your template. Sorry to sound harsh but the point of a separated view is to remove the processing code from the view layer. The template systems described above along with Template Toolkit just pass in an object / hash so you can access it.
why not pass $user as a hashref like:
$user = {
'name' => 'John',
'id' => '3454'
};
this will allow you to access 'name' with:
$user->{'name'};
Otherwise, it's likely that you have that you're doing something like:
template calls $user->query();
method calls DB to get value
method returns value
That's soooo much more expensive to make a database query than to pass the hash/object reference to the template. You may want to check out some code profiling tools like Devel::NYTProf to see what part of the code execution is really slowing you down. I'm skeptical that the eval is bogging down your program so much that you need to optimize out eval. Sounds like the code inside eval is what is slowing you down.

Related

Ruby, evaluate one ruby function or another using the same DO block

In ERB or HAML, I need to be able to evaluate one function, or a different one, based on the output of a conditional, while using the same HTML block for either one.
In HAML, it would like something like this:
- is_a = #thing.is_a?
= (is_a ? f.method_a : f.method_b) arg_1, |block_arg1| do
#thing
.blah
.inner-thing
= block_arg1.some_method
Notice how, on line 2 of my pseudocode, I am trying to evaluate either one function, or the other, based upon a conditional. But I need pass the same arguments to either, especially since I don't want to have to re-type the DO block.
Maybe I could avoid that problem ("I don't want to re-type...") by making that DO block a named function? How does one turn a HAML or ERB block into a named Ruby function?
I'm using Ruby-on-Rails 4. Not that it matters; this looks like more of a ruby syntax question than a framework question.
You seem to be looking for #send
- is_a = #thing.is_a?
= f.send(is_a ? :method_a : :method_b, arg_1) do |block_arg|
(...)

call/invoke different methods based on datatypes in GDB

I am trying to define a command in gdb which is sort of a wrapper which will call respective method based on the datatype of the argument passed to it.
I have tried something like
set $datatype = whatis $arg0
But it does not seem to work.
I am trying to write something like this
define gprint
set $datatype = //somehow get the datatype of arg
if $datatype == *type1
p print_type1(*$arg0)
end
if $datatype == type1
p print_type1($arg0)
end
if $datatype == type2
p $arg0->print()
end
//
//
// Some more datatypes
//
//
end
There's no convenient way to do this from the gdb command line, because there is no good way to smuggle a type into an expression.
It can be done the hard way using the "standard hack" -- use "set logging" to write the type to a file, then "shell" to rewrite the file to a gdb script, and then "source" to load that script. However, this is very painful.
Instead, it is much simpler to use Python. Here you have several options.
Since it seems like you want to make the display of some values vary by type, I would suggest using the gdb "pretty printing" feature. This feature is designed for exactly this scenario. It integrates nicely with print, bt, and other gdb commands.
However, if you are not doing that, and you'd still rather write your own gprint command, you still have options: you can write the command entirely in Python, which has access to both expressions and types. Or, you can write Python convenience functions that do what you like. You can see an example of the latter in my gdb-helpers repository; in particular see the $_typeof function.

Ruby style tips: Avoid eval, and keep things clear and orderly

I'm confused on this one. I have a couple of viable solutions, but I don't like either of them. The problem at hand is that I am trying to generate a CSV in a Rails application. In my application specifically, I have a lot of values, around 30. Many of the values I would like displayed are also on associations, thus making the lines even longer... They look something like this (don't bother to read, just wanted you to have an idea of what i was talking about):
[piece.client.organization, piece.client.category, piece.client.name , piece.campaign.name, piece.name, piece_url(piece.id), piece.campaign.election_date, piece.campaign.win_loss, piece.final_date, piece.local_photos, piece.killed, piece.format_list, piece.artist_list, piece.partner_list, piece.account_executive_list, piece.out_of_stock, piece.total_intake, piece.campaign.candidate_tags, piece.client.spec_list, piece.campaign.mail_poll]
Except that they're even longer and more unwieldy. They work, but they make me feel bad inside. This is when I had the idea that I would just put them in a two-dimensional array, it instantly made the data look much more readable:
[["Client", piece.client.organization],
["Category", piece.client.category],
["Client Name", piece.client.name] ,
...
["Campaign Name", piece.campaign.name],
["Piece Name", piece.name]]
That's great, now I can just loop over it to create my CSV rows... However, it will blow up based on where I need to define it as my "piece" is undefined. So then, I thought... what if I just wrap the second arguments in quotes and call eval on them later on when I need them? Then I looked it up, and people seem to say to use eval only to save lives...
Can anyone think of a simpler way to keep all of my data paired with column names, but maybe not use eval? Or maybe suggest that this would be a good use case for eval?
You can usually avoid eval by using blocks instead. For example, re-define your structure in terms of method calls:
columns = [
[ "Client", lambda { |piece| piece.client.organization } ],
[ "Category", lambda { |piece| piece.client.category } ],
# ...
]
Then when iterating over your block, do something like this:
pieces.each do |piece|
spec.each do |label, proc|
value = proc.call(piece)
# ... Do whatever you need here
end
end
Defining blocks (Proc internally) can help define methods for doing things while deferring variable binding to some point in the future.
eval has a reputation for being dangerous because it can execute anything. It's best to avoid it unless there really is no other way.

When is `eval` in Ruby justified?

"Is 'eval' supposed to be nasty?" inspired this one:
Mostly everybody agrees that eval is bad, and in most cases there is more elegant/safer replacement.
So I wanted to ask: if eval is misused that often, is it really needed as a language feature? Is it doing more evil than good?
Personally, the only place I find it useful is to interpolate strings provided in config file.
Edit: The intention of this question is to get as many real-life cases as possible when eval is the only or the best solution. So please, don't go into "should a language limit a programmer's creativity" direction.
Edit2: And when I say eval, of course I refer to evaling string, not passing ruby block to instance_eval or class_eval.
The only case I know of (other than "I have this string and I want to execute it") is dynamically dealing with local and global variables. Ruby has methods to get the names of local and global variables, but it lacks methods to get or set their values based on these names. The only way to do AFAIK is with eval.
Any other use is almost certainly wrong. I'm no guru and can't state categorically that there are no others, but every other use case I've ever seen where somebody said "You need eval for this," I've found a solution that didn't.
Note that I'm talking about string eval here, by the way. Ruby also has instance_eval, which can take either a string or a block to execute in the context of the receiver. The block form of this method is fast, safe and very useful.
When is it justified? I'd say when there's no reasonable alternative. I was able to think of one use where I can't think of an alternative: irb, which, if you dig deep enough (to workspace.rb, around line 80 in my copy if you're interested) uses eval to execute your input:
def evaluate(context, statements, file = __FILE__, line = __LINE__)
eval(statements, #binding, file, line)
end
That seems pretty reasonable to me - a situation where you specifically don't know what code you're going to have to execute until the very moment that you're asked to do so. Something dynamic and interactive seems to fit the bill.
The reason eval is there is because when you need it, when you really need it, there are no substitutes. There's only so much you can do with creative method dispatching, after all, and at some point you need to execute arbitrary code.
Just because a language has a feature that might be dangerous doesn't mean it's inherently a bad thing. When a language presumes to know more than its user, that's when there's trouble.
I'd argue that when you find a programming language devoid of danger, you've found one that's not very useful.
When is eval justified? In pragmatic terms, when you say it is. If it's your program and you're the programmer, you set the parameters.
There is one very important use-case for eval() which cannot (AFAIK) be achieved using anything else, and that is to find the corresponding object reference for a binding.
Say you have been passed a block but (for some reason) you need access to object context of the binding, you would do the following:
obj = eval('self', block.binding)
It is also useful to define the following:
class Proc
def __context__
eval('self', self.binding)
end
end
IMO mostly for Domain Specific Languages.
"Evaluation Options in Ruby" is an article by Jay Fields about it on InfoQ.
eval is a tool, it is neither inherently good nor evil. It is justified whenever you are certain it is the right tool for what you are trying to accomplish.
A tool like eval is about evaluating code at runtime vs. "compile" time. Do you know what the code is when you launch Ruby? Then you probably don't need eval. Is your code generating code during runtime? then you probably need to eval it.
For example, the methods/functions needed in a recursive decent parser depend on the language being parsed. If your application builds such a parser on-the-fly, then it might make sense to use eval. You could write a generalized parser, but it might not be as elegant a solution.
"Programatically filling in a letrec in Scheme. Macros or eval?" is a question I posted about eval in Scheme, where its use is mostly unavoidable.
In general eval is a useful language feature when you want to run arbitrary code. This should be a rare thing but maybe you are making your own REPL or you want to expose the ruby run-time to the end user for some reason. It could happen and that is why the feature exists. If you are using it to work around some part of the language (e.g. global variables) then either the language is flawed or your understanding of the language is flawed. The solution is typically not to use eval but to either better understand the language or pick a different language.
It's worth noting that in ruby particulary instance_eval and class_eval have other uses.
You very likely use eval on a regular basis without even realizing it; it's how rubygems loads the contents of a Gemspec. Via rubygems/lib/specification.rb:
# Note: I've removed some lines from that listing to illustrate the core concept
def self.load(file)
code = File.read(file)
begin
_spec = eval code, binding, file # <-------- EVAL HAPPENS HERE
if Gem::Specification === _spec
return _spec
end
warn "[#{file}] isn't a Gem::Specification (#{_spec.class} instead)."
rescue SignalException, SystemExit
raise
rescue SyntaxError, Exception => e
warn "Invalid gemspec in [#{file}]: #{e}"
end
nil
end
Typically, a gem specification would look like this:
Gem::Specification.new do |s|
s.name = 'example'
s.version = '0.1.0'
s.licenses = ['MIT']
s.summary = "This is an example!"
s.description = "Much longer explanation of the example!"
s.authors = ["Ruby Coder"]
s.email = 'rubycoder#example.com'
s.files = ["lib/example.rb"]
s.homepage = 'https://rubygems.org/gems/example'
s.metadata = { "source_code_uri" => "https://github.com/example/example" }
end
Note that the gemspec file simply creates a new object but does not assign it nor send it anywhere.
Trying to load or require this file (or even executing it with Ruby) will not return the Gem::Specification value. eval is the only way to extract the value defined by an external ruby file.
One use of eval is compiling another language to ruby:
ruby_code = "(def foo (f a b) (mapv f (cons a b)))".compile_to_ruby
# "foo_proc = ->(f a b) { mapv_proc.call(f, (cons_proc.call(a, b)) }"
eval ruby_code
I use a 3D modeling software that implemented Ruby for writing custom text macros. In that software we are given access to model data in the form of name:value pairs accessed using the following format:
owner.name
#=> value
So for a 36 inch tall cabinet, I could access the height and convert its value to feet like so:
owner.height.to_f / 12
The main problem is that objects in that software have no unique identifiers aside from something called their schedule_number. If I want to name a variable using the schedule_number in the variable name so that I can call and use that value elsewhere, the only possible way I know to do that is by using eval:
eval "#{owner.schedule_number} = owner.height"

When to use blocks

I love Ruby blocks! The idea behind them is just very very neat and convenient.
I have just looked back over my code from the past week or so, which is basically every single ruby function I ever have written, and I have noticed that not a single one of them returns a value! Instead of returning values, I always use a block to pass the data back!
I have even caught myself contemplating writing a little status class which would allow me to write code like :
something.do_stuff do |status|
status.success do
# successful code
end
status.fail do
# fail code
puts status.error_message
end
end
Am I using blocks too much? Is there a time to use blocks and a time to use return values?
Are there any gotchas to be aware of? Will my huge use of blocks come and bite me sometime?
The whole thing would be more readable as:
if something.do_stuff
#successful code
else
#unsuccessful code
end
or to use a common rails idiom:
if #user.save
render :action=>:show
else
#user.errors.each{|attr,msg| logger.info "#{attr} - #{msg}" }
render :action=>:edit
end
IMHO, avoiding the return of a boolean value is overuse of code blocks.
A block makes sense if . . .
It allows code to use a resource without having to close that resource
open("fname") do |f|
# do stuff with the file
end #don't have to worry about closing the file
The calling code would have to do non-trivial computation with the result
In this case, you avoid adding the return value to calling scope. This also often makes sense with multiple return values.
something.do_stuff do |res1, res2|
if res1.foo? and res2.bar?
foo(res1)
elsif res2.bar?
bar(res2)
end
end #didn't add res1/res2 to the calling scope
Code must be called both before and after the yield
You see this in some of the rails helpers:
&lt% content_tag :div do %>
&lt%= content_tag :span "span content" %>
&lt% end -%>
And of course iterators are a great use case, as they're (considered by ruby-ists to be) prettier than for loops or list comprehensions.
Certainly not an exhaustive list, but I recommend that you don't just use blocks because you can.
This is what functional programming people call "continuation-passing style". It's a valid technique, though there are cases where it will tend to complicate things more than it's worth. It might be worth to relook some of the places where you're using it and see if that's the case in your code. But there's nothing inherently wrong with it.
I like this style. It's actually very Ruby-like, and often you'll see projects restructure their code to use this format instead of something less readable.
Returning values makes sense where returning values makes sense. If you have an Article object, you want article.title to return the title. But for this particular example of callbacks, it's stellar style, and it's good that you know how to use them. I suspect that many new to Ruby will never figure out how to do it well.

Resources