I would like to load a theme for a cms I’m building.. I was thinking of having a file called name_of_theme.themespec .. I would load this.. similar to what Bundler dues with gemspecs.. I was thinking that inside this file I would have something like:
Theme.new do |t|
t.value = 'hi'
end
I’d like to capture this theme instance after loading the script.. Should I just grab the contents of the file and eval them? This leads me to a follow up question is there any difference between loading a file.. and reading the contents and eval’ing.. I know that ‘eval’ is often considered to be the harbinger of destruction… maybe this use case is ok?
FOLLOW UP
Based on the selected answer.. why is it that I get:
evaluationContext = Fiber.new {$SAFE = 4; Fiber.yield binding}.resume
=> #<Binding:0x007f85fc8a0fc8>
a = evaluationContext.eval('puts $SAFE')
=> 0
Well, there are a few differences, but if you’re already accepting external code, the gapping security hole is the same size with either
evalorrequire. In this case, actually,evalmight be more secure, because it can let you have control over the namespace and safe level at which the code executes. This is important, because, say, your app deals with someones email password. If you let the theme execute in the main namespace (require), it can do dastardly things like redefiningKernel#getsto log data to a malicious server, etc. Although it sounds far fetched, it’s better to be safe. SO here’s how you can do a secure load of this type:Note: Any code called from the theme will be executed under $SAFE 4, so while for most things this is good (they can’t call
system("rm -rf /")), fi there is any small amount of $SAFE 0 code that needs to be callable from the theme, the code has to be created in a lambda while you are still in safe level 0, and then passed to the code in safe level 4 (because lambdas retain their safe value).EDIT: Try replacing the eval line with this: