musictheory / NilScript

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

Have class object also have a wrapper method #26

Closed IngwiePhoenix closed 9 years ago

IngwiePhoenix commented 9 years ago

I just played around a little, and found out, that this is not possible:

@implementation MyImpl
+(id)myFunc {
    console.log("Meep!");
}
@end

var MyExp = { func = [MyImpl myFunc] };
// of course, this would call the function. But the following won't work either:
var MyExp2 = { func = MyImpl.myFunc };

Whilst the compiled code actually does create an object with a cosntructor, it doesnt create member functions. Maybe its a bit above what oj should do, but I was just curios about it. For the meantime, I'll have to write a small callback myself - but thats okay.

iccir commented 9 years ago

I'm not quite following:

+myFunc is declared to return type id, but you aren't returning anything. Hence, func will be undefined in the above example.

Just like in Obj-C, you can't grab a reference to a function (well, you can, if you poke around with the oj internals, but that's probably going to break in the future). What you can do, however, is use selectors:

var  sel = @selector(myFunc);
[MyImpl performSelector:sel];

This should allow you to implement the target/action design pattern found in Cocoa.

You can also do callbacks such as the following:

@implementation Foo

- (void) performWithCallback:(Function)callback
{
    var a = 2;
    var b = 4;

    callback(a + b);
}

@end

var foo = [[Foo alloc] init];
[foo performWithCallback:function(result) {
    console.log(result);
}];
IngwiePhoenix commented 9 years ago

Yeah, you named it: reference to a function. That was what I was hoping for, for public - convenience - methods that is. But what you provided is quite helpful too. But is there a way to „grab“ a reference to a function in oj at all?

Am 28.10.2014 um 08:28 schrieb Ricci Adams notifications@github.com:

I'm not quite following:

+myFunc is declared to return type id, but you aren't returning anything. Hence, func will be undefined in the above example.

Just like in Obj-C, you can't grab a reference to a function (well, you can, if you poke around with the oj internals, but that's probably going to break in the future). What you can do, however, is use selectors:

var sel = @selector(myFunc); [MyImpl performSelector:sel]; This should allow you to implement the target/action design pattern found in Cocoa.

You can also do callbacks such as the following:

@implementation Foo

  • (void) performWithCallback:(Function)callback { var a = 2; var b = 4;

    callback(a + b); }

@end

var foo = [[Foo alloc] init]; [foo performWithCallback:function(result) { console.log(result); }]; — Reply to this email directly or view it on GitHub https://github.com/musictheory/oj/issues/26#issuecomment-60718469.

iccir commented 9 years ago

Not directly, as the reference to self/this would be lost (just as it is in JavaScript). However, if you use self within a closure, the value of self remains the same.

For example, in our source base, we do a lot of this (with underscore.js):

- (void) doSomethingToObject:(Object)object
{
    /* code here */
}

- (void) doSomethingToArray:(Array)array
{
    _.each(array, function(x) {
        // self correctly points to the right object, no need to bind()
        [self doSomethingToObject:x];
   });
}
iccir commented 9 years ago

You also get this behavior if you use ivars inside of the closure.

iccir commented 9 years ago

Note: this is all oj 1.0. I really need to merge the 1.0 branch into master, but I haven't had time (and I still need to research how to publish it properly on npm).

IngwiePhoenix commented 9 years ago

npm publish inside the module itself is all you need. Just correct the version number accordingly and make sure oyu are logged in the same accountu nder which you did your previous publishing. Then you should be good to go.

While you are preparing your NPM release, make sure that if someone require()'s the module, they get something proper in return. That is why i voted for you to set main to src/compiler.js. You can, however, also create a "index" file that has: {compiler:... , runtime:... }. Just my few cents on that topic.

And thanks! I have understood out how to work it out now! :)

iccir commented 9 years ago

I think this issue is taken care of? Ingwie, please feel free to file more bugs if you have more questions :)