musictheory / NilScript

Objective-C-style language superset of JavaScript with a tiny, simple runtime
Other
50 stars 5 forks source link

Rather stupid issue :) #42

Closed IngwiePhoenix closed 9 years ago

IngwiePhoenix commented 9 years ago

So I finally updated connect-oj with some version informations and yadda yadda - and while I was at it, i also embedded it into my CMS! So my OJ files are now preprocessed, cached and delivered. Wut!

But when I put together a basic example, I got this:

@implementation BIRD3App {
    var sio;
}
+(id)init {
    console.log("Init...");
    sio = io();
    console.log("Connected using:", sio.io.engine.transport.name);
    return self;
}
-(SocketIO)socket {
    return sio;
}
@end

var app = [BIRD3App init];
var sio = [app socket];

Output:

JQMIGRATE: Logging is active
BIRD3.oj:6 Init...
BIRD3.oj:8 Connected using: polling
c_86d0099bfa920708f5f727ace32fd4fe.js:18679 Uncaught Error: Unrecognized selector: socket sent to instance function BIRD3App() { this.$oj_i_BIRD3App$sio=null;this.constructor = BIRD3App;this.$oj_id = ++$oj_oj._id;}
c_86d0099bfa920708f5f727ace32fd4fe.js:14362 XHR finished loading: GET "http://localhost:8080/socket.io/?EIO=3&transport=polling&t=1421187025260-0".
c_86d0099bfa920708f5f727ace32fd4fe.js:14362 XHR finished loading: GET "http://localhost:8080/socket.io/?EIO=3&transport=polling&t=1421187025338-1&sid=V9US_jzH_c-JJqbQAAAH".

The obfuscated script name basically reffers to the dynamically concated file that PHP did for me. I use that to save me some space. :)

What am I doing wrong here, that causes this error though?

iccir commented 9 years ago

You are missing a call to +alloc :) oj is like Objective-C: +alloc allocates the memory (or does a new() in our case) and zero-fills it, -init is then responsible for initializing the ivars.

So you need to do two things: 1) Change the bottom line to var app = [[BIRD3App alloc] init];

2) Change +init to -init and make sure you call [super init]. A more traditional init method would look like this:

- (id) init {
    if (self = [super init]) {
        console.log("Init...");
        sio = io();
        console.log("Connected using:", sio.io.engine.transport.name);
    }

    return self;
}
IngwiePhoenix commented 9 years ago

Ohhh! I totally forgot that init was an instance method… x.x I have been down with C++ for too long, srsly. =)

Should probably add a warning though, if you’re trying to access a convenience method as an instance method. Because I did use +alloc but then I got no result at all - which is why I moved it out.

Thanks for the help! Will change and test now.

Am 14.01.2015 um 00:08 schrieb Ricci Adams notifications@github.com:

You are missing a call to +alloc :) oj is like Objective-C: +alloc allocates the memory (or does a new() in our case) and zero-fills it, -init is then responsible for initializing the ivars.

So you need to do two things: 1) Change the bottom line to var app = [[BIRD3App alloc] init];

2) Change +init to -init and make sure you call [super init]. A more traditional init method would look like this:

iccir commented 9 years ago

Classes are objects too (in Obj-C), so there isn't a compiler warning on '-init', since calling [NSString init]; legally sends -init to an object of class Class. However, there is a runtime exception that is then thrown (Which we could mimic in oj).

For example, [NSString init] will throw +[NSString<0x7fff78ebc188> init]: cannot init a class object. at runtime.

iccir commented 9 years ago

In this case, however, a runtime exception would not have been triggered (if it existed), since you explicitly added an +(id)init method (which is legal in Obj-C too).