trifork / erjang

A JVM-based Erlang VM
http://www.erjang.org
Apache License 2.0
725 stars 62 forks source link

LFE Can't handle java.lang.String objects from Erjang #84

Open oubiwann opened 10 years ago

oubiwann commented 10 years ago

Here's a simple example of the problem in action:

> (set str (java.lang.String:new '"some string"))
exception error: badarg
  in (: lfe_io_pretty print1 "some string")
>

This seems to be a problem of displaying java.lang.String objects. Using a let (an operation which doesn't attempt to display the result) gets around the problem highlighted in the example above:

> (let ((str (java.lang.String:new '"some string")))
     (java:call str 'getClass '() '()))
java.lang.String
>
oubiwann commented 10 years ago

I followed up last night on the mail list about this one; Kresten had previously given this excellent information:

"… is probably some error in the value mapping. Its a bit complex, and if you want to dive into it I can explain more. But essentially a JavaObject thing can act as more than one kind of erlang term, depending on how you deconstruct it with pattern matching. For Java strings, we keep the string around, wrapped in a synthetic cons cell that will allow you to access head and tail..."

In LFE's src/lfe_io_pretty.erl, I made the following change:

@@ -47,6 +47,10 @@ print1([quote,E], D, I, L) -> ["'",print1(E, D, I+1, L)];
 print1([backquote,E], D, I, L) -> ["`",print1(E, D, I+1, L)];
 print1([unquote,E], D, I, L) -> [",",print1(E, D, I+1, L)];
 print1(['unquote-splicing',E], D, I, L) -> [",@",print1(E, D, I+2, L)];
+%% Handle specialized forms from Erjang
+print1([Head|Tail], _, _, _) when is_list(Head) and is_list(Tail) ->
+    Head ++ Tail;
+%% Continue with cons matching ...
 print1([Car|_]=List, D, I, L) ->
     %% Handle printable lists specially.
     case io_lib:printable_list(List) of

At first, this didn't seem to be stomping on any of the other patterns in the LFE pretty printer, but after a bit more testing, I'm unconvinced. I'm going to dig into this some more and explore some more edge cases.

I will open a new ticket in LFE for all of this.

krestenkrab commented 10 years ago

Does your change make it work? Because that could give some good hints for where to go bug-hunting in the Erjang code.

oubiwann commented 10 years ago

Excellent -- will try again with the change (once I've gotteb it to a point where I think Robert might approve!).

oubiwann commented 10 years ago

I'm going to update this ticket to be more specific, now that we're getting closer to the issue. Here was the original description, for future reference:

The following returns an error in LFE:

> (java.lang.System:getProperty '"java.io.tmpdir")
exception error: badarg
  in (: lfe_io_pretty
        print1
       "/var/folders/c8/2cl5l5_102b1qq8bh05t7xw40000gn/T/")

The same call in Erjang-proper:

10> 'java.lang.System':getProperty("java.io.tmpdir").
"/var/folders/c8/2cl5l5_102b1qq8bh05t7xw40000gn/T/"

This may be an issue in LFE; I will investigate and report back my findings to this ticket.