英文:
Using `include` and `using` inside a string of code
问题
我正在尝试评估一个包含Ruby代码的字符串,在实例的上下文中进行评估,同时保留标准的Ruby方法,如using
(用于细化)和include
。
这是我最简化的示例。我希望用户代码(字符串)能够原样工作,而无需对其进行修改。Context#run
方法是我希望进行必要更改的地方。
require 'fileutils'
module SomeUserRefinement
refine String do
def header
"=== #{self} ==="
end
end
end
class Context
def run(code)
instance_eval code
end
def some_instance_method
puts "works"
end
end
user_code = <<~CODE
using SomeUserRefinement # not working
include FileUtils # not working
puts 'Caption'.header
some_instance_method
CODE
context = Context.new
context.run user_code
英文:
I am trying to evaluate a string that contains Ruby code, in the context of an instance, while maintaining standard Ruby methods such as using
(for refinements) and include
.
Here is my most stripped down example. I would like to make the user code (string) work as is, without modification to it. The Context#run
method is where I am hoping to make the necessary changes.
require 'fileutils'
module SomeUserRefinement
refine String do
def header
"=== #{self} ==="
end
end
end
class Context
def run(code)
instance_eval code
end
def some_instance_method
puts "works"
end
end
user_code = <<~CODE
using SomeUserRefinement # not working
include FileUtils # not working
puts 'Caption'.header
some_instance_method
CODE
context = Context.new
context.run user_code
答案1
得分: 2
您的整体意图除了“...我想让用户代码(字符串)原封不动地工作,不需要对其进行修改”之外,有点不太清楚,这在任何情况下可能都不起作用(例如,如果用户代码不好,它将始终失败,就像这里一样)
简短回答
按设计,您所请求的实现根本不可能。此外,您的示例尝试混合使用实例方法和类实例方法,同时使用相同的接收器,这也是不可能的。
更长的回答
如果您发布了实际的错误消息,它将显示:
undefined method `using' for #<Context:0x00007ff65eda4498> (NoMethodError)
这是因为using
不是一个实例方法。(include
也适用相同的规则)
好吧,让我们尝试利用您的实例的特殊类(eigenclass)
class Context
def run(code)
singleton_class.instance_eval code
end
end
新错误
`using': Module#using is not permitted in methods (RuntimeError)
如果我们阅读refinements的文档,我们会看到:
作用域
您可以在顶层、类和模块内激活refinements。您不能在方法作用域内激活refinements。 Refinements会在当前类或模块定义结束时激活,或者在顶层使用时,在当前文件结束时激活。
include
没有相同的限制,模块可以在方法作用域内包含在实例的eigenclass中;但是,您的代码还需要能够在相同的上下文中使用相同的接收器调用some_instance_method
,这是不可能的。
英文:
Your overall intent is a bit unclear other than "...I would like to make the user code (string) work as is, without modification to it", which may or may not work in any given circumstance (e.g. if the user code is no good then it will always fail, as it does here)
Short Answer
Your requested implementation is simply not a functional possibility by design. Additionally your example attempts to mix and match instance methods and class instance methods while using the same receiver, which is also not possible.
Longer Answer
Had you posted the actual error message it would have shown:
undefined method `using' for #<Context:0x00007ff65eda4498> (NoMethodError)
This is because using
is not an instance method. (same applies to include
)
Okay so let's try to leverage the eigenclass for your instance
class Context
def run(code)
singleton_class.instance_eval code
end
end
New error
`using': Module#using is not permitted in methods (RuntimeError)
If we read through the docs for refinements we see:
> Scope
>
>You may activate refinements at top-level, and inside classes and modules. You may not activate refinements in method scope. Refinements are activated until the end of the current class or module definition, or until the end of the current file if used at the top-level.
include
does not have the same limitation and modules can be included in the eigenclass of an instance in a method scope; however your code also needs to be able to call some_instance_method
in the same context with the same receiver, which is not possible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论