如何在Clojure中使用interop访问默认访问方法? [英] How to access a default access method using interop in Clojure?

查看:205
本文介绍了如何在Clojure中使用interop访问默认访问方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Clojure REPL上执行以下操作:

  user => (ns clojure.lang)
nil
clojure.lang => (def tran(clojure.lang.LockingTransaction。))
#'clojure.lang / tran
clojure.lang => (.getReadPoint tran)

这会得到以下结果:

  IllegalArgumentException找不到匹配字段:getreadPoint类clojure.lang.LockingTransaction clojure.lang.Reflector.getInstanceField(Reflector.java:271)

现在这个方法



现在我想我应该可以从REPL访问默认的访问方法。



我的问题是:如何使用Clojure中的interop访问默认访问方法



有一个古怪的库, vinyasa ,这使这些技巧更容易拉。



这是使用这个奇怪的图书馆的复制会话的抄本:

  user => ; (require'[vinyasa.inject:as inject])
nil
user => (inject / in clojure.core [vinyasa.reflection。>。*。%。%>。&。> ns。> var])
[]
user => ; (def locking-transaction(clojure.lang.LockingTransaction。))
#'user / locking-transaction
user => (def get-read-point(。?clojure.lang.LockingTransactiongetReadPoint))
#'user / get-read-point
user => get-read-point
(#[getReadPoint ::(clojure.lang.LockingTransaction) - > void])
user => ((第一个获取读取点)锁定事务)
nil

vinyasa ,并按照库的建议,将其奇怪命名的宏注入 clojure.core 。使用。?宏我们找到受保护的方法,vm通常会阻止我们访问,通过反射得到一个可以用来规避虚拟机安全性的版本。最后,我们访问并调用 LockingTransaction 对象上的方法,并获得期望的返回值( nil )。 p>

请注意,在运行时将符号插入其他命名空间在Clojure中不被认为是正常或可取的行为,也不会绕过VM保护,您可以轻松地将虚拟机隔离或导致非常奇怪通过反射调用受保护或私有方法的错误。


I'm doing the following on a Clojure REPL:

user=> (ns clojure.lang)
nil
clojure.lang=> (def tran (clojure.lang.LockingTransaction.))
#'clojure.lang/tran
clojure.lang=> (.getReadPoint tran)

This gives the following result:

IllegalArgumentException No matching field found: getReadPoint for class clojure.lang.LockingTransaction  clojure.lang.Reflector.getInstanceField (Reflector.java:271)

Now this method does exist.

Now I think I should be able to access default access methods from the REPL.

My question is: How to access a default access method using interop in Clojure?

解决方案

It's possible, but it requires some dirty tricks.

There's a weird library, vinyasa, which makes these tricks much easier to pull.

Here's a transcript from a repl session using this odd library:

user=> (require '[vinyasa.inject :as inject])
nil
user=> (inject/in clojure.core [vinyasa.reflection .> .? .* .% .%> .& .>ns .>var])
[]
user=> (def locking-transaction (clojure.lang.LockingTransaction.))
#'user/locking-transaction
user=> (def get-read-point (.? clojure.lang.LockingTransaction "getReadPoint"))
#'user/get-read-point
user=> get-read-point
(#[getReadPoint :: (clojure.lang.LockingTransaction) -> void])
user=> ((first get-read-point) locking-transaction)
nil

Here we load up vinyasa, and as recommended by the library, inject its oddly named macros into clojure.core. Using the .? macro we find the protected method which the vm would usually prevent us from accessing, and via reflection get a version which can be used to circumvent the VM's security. Finally we access and call the method on our LockingTransaction object, and get the expected return value (nil).

Be aware that inserting symbols into other namespaces at runtime is not considered normal or desirable behavior in Clojure, nor is bypassing VM protections, and you can easily segfault the VM or cause very weird bugs by calling protected or private methods via reflection.

这篇关于如何在Clojure中使用interop访问默认访问方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆