<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged proxy</title>
<link>https://ask.clojure.org/index.php/tag/proxy</link>
<description></description>
<item>
<title>Using proxy to extend MemoryStream fails on Close</title>
<link>https://ask.clojure.org/index.php/12549/using-proxy-to-extend-memorystream-fails-on-close</link>
<description>&lt;p&gt;For some unit tests, I need to be able to read the contents of a &lt;code&gt;MemoryStream&lt;/code&gt; after it has been closed. As this isn't possible, I want to create a memory stream proxy where the call to &lt;code&gt;Close&lt;/code&gt; is a no-op, allowing me to read from it even when code outside of my control has attemped closing it. This however won't work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;REPL&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(import [System.IO MemoryStream StreamWriter])
(let [stream (proxy [MemoryStream] [] (Close [] (println &quot;close!&quot;)))]
  (doto (StreamWriter. stream)
        (.Write &quot;testing&quot;)
        (.Close)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;output&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;close!
Execution error (InvalidProgramException) at System.Diagnostics.StackFrame/Write (NO_FILE:0).
Cannot create boxed ByRef-like values.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While it's evident my proxied &lt;code&gt;Close&lt;/code&gt; method is called, an error is thrown just after.&lt;/p&gt;
</description>
<category>ClojureCLR</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12549/using-proxy-to-extend-memorystream-fails-on-close</guid>
<pubDate>Sun, 15 Jan 2023 00:08:50 +0000</pubDate>
</item>
<item>
<title>using `proxy` might make an otherwise additive change breaking</title>
<link>https://ask.clojure.org/index.php/10383/using-proxy-might-make-otherwise-additive-change-breaking</link>
<description>&lt;p&gt;Given an interface&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface Foo {
    void bar(Object o);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a proxy over that interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(proxy [Foo] []
  (bar [o] (baz o)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the interface gets updated to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface Foo {
  void bar(Object o);

  // java 8 default method, quote from 
  // https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
  // &quot;Default methods enable you to add new functionality to the
  // interfaces of your libraries and ensure binary compatibility
  // with code written for older versions of those interfaces.&quot;
  default void bar(Object o, Object p) {
    bar(o);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Calls to &lt;code&gt;instanceCreatedByProxy.bar(o, p)&lt;/code&gt; will not work as it could be expected.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;reify&lt;/code&gt; is not affected by this.&lt;/p&gt;
&lt;p&gt;Repro repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/imrekoszo/proxy-default&quot;&gt;https://github.com/imrekoszo/proxy-default&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;There is no indication of this behavior &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy&quot;&gt;in the docstring&lt;/a&gt; of &lt;code&gt;proxy&lt;/code&gt;, the only reference I saw to this is an &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojuredocs.org/clojure.core/proxy#example-542692d4c026201cdc327040&quot;&gt;example on clojuredocs&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This is troublesome as it might prevent an otherwise non-breaking library upgrade. If the code calling &lt;code&gt;proxy&lt;/code&gt; is under one's control they could use &lt;code&gt;reify&lt;/code&gt; instead (especially as this is &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/reference/datatypes#_reify&quot;&gt;recommended in the official docs&lt;/a&gt;). However if it is in an external library this is not a viable workaround.&lt;/p&gt;
&lt;p&gt;Is this a bug or a known limitation of &lt;code&gt;proxy&lt;/code&gt;?&lt;br&gt;
If the latter, then could this perhaps be made more visible, for example through a warning in the docstring?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Edit:&lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians-log.clojureverse.org/clojure/2021-03-29/1617036667.062000&quot;&gt;link to original slack thread&lt;/a&gt;&lt;br&gt;
- added link to &lt;code&gt;reify&lt;/code&gt; recommendation&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10383/using-proxy-might-make-otherwise-additive-change-breaking</guid>
<pubDate>Tue, 30 Mar 2021 10:33:11 +0000</pubDate>
</item>
<item>
<title>Implementing a type or record to support defmethod in CLJ</title>
<link>https://ask.clojure.org/index.php/9045/implementing-a-type-or-record-to-support-defmethod-in-clj</link>
<description>&lt;p&gt;Thanks to &lt;code&gt;IMultiFn&lt;/code&gt; in CLJS types and records can be easily extended to behave as multimethods. For example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;`&lt;/code&gt;(defrecord MyMulti&lt;br&gt;
  [add-method remove-method dispatch-fn method-table]&lt;br&gt;
  IMultiFn&lt;br&gt;
  (-add-method [_ dispatch-val f]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(add-method dispatch-val f))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (-remove-method [_ dispatch-val]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(remove-method dispatch-val))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (-methods [_] @method-table))&lt;/p&gt;
&lt;p&gt;(def my-multi (-&amp;gt;MyMulti ...))&lt;/p&gt;
&lt;p&gt;(defmethod my-multi :foo&lt;br&gt;
  [x]&lt;br&gt;
  ...)&lt;br&gt;
&lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In Clojure however this isn't as easy because multimethods are not implemented using protocols. IS there ANY way to make a record or type to work with defmethod in CLJ?&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
</description>
<category>Multimethods</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9045/implementing-a-type-or-record-to-support-defmethod-in-clj</guid>
<pubDate>Fri, 17 Jan 2020 18:37:33 +0000</pubDate>
</item>
</channel>
</rss>