[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-users] there's something i dont understand



On Dec 24, 2007, at 7:04 AM, Vytautas Jancauskas wrote:
What options for abstraction do i have in sclang? Obviously classes but don't those only get evaluated when sclang get's started? I tried defining a class and then sending it to sclang from emacs but that didn't work. Is that possible? Functions don't really cut it for this big GUI application i am planning, so i was wondering... 

Get my ddwPrototype quark from svn, or use the attached.

You're right, classes are set in stone at compile time and there is no way to add them at runtime. That's a bother for code that has to change a lot, which is why most of the time I use classes only for "utility" functionality (things you will use repeatedly that generally remain stable, don't need a lot of customization).

For just about everything else, I'm very fond of prototype-based programming - http://en.wikipedia.org/wiki/Prototype-based_programming . It seems I'm becoming something of an evangelist for prototypes...

Because of the way the interpreter works, the one thing to watch out for is variable or method names that match methods defined in the Proto class itself, or in Object. Those get "swallowed" by the interpreter and not relayed into the proto environment.

Since you're going to be working with GUIs, also be aware that callback functions have to be explicitly attached to the environment, as demonstrated below. It's not hard, just something to remember.


// This is an object
~object = Proto({
// These are variables
~lo = 0;
~hi = 9;
// these are methods
~getRandom = { |lo, hi|
rrand(lo ? ~lo, hi ? ~hi)
};
~printRandom = { |lo, hi|
"Here's a random number: %\n".postf(~getRandom.value(lo, hi));
currentEnvironment
};
});

// ... you can call it like a regular object
~object.getRandom;
~object.printRandom(100, 200);

// ... and change its variables like a regular object
~object.hi = 20;
~object.getRandom;

// you can dump the contents of its variables, or ask it for its interface
~object.listVars;
~object.help;

// you can make a new instance
~object2 = ~object.copy;

// ... or a "subclass" that inherits from the original
~object3 = ~object.clone({
~getRandom = { |lo, hi| exprand(lo ? ~lo, hi ? ~hi) };
});

// ... and even overwrite methods on the fly
~object.printRandom = { |lo, hi|
"Here's a random number, times 2: %\n".postf(~getRandom.value(lo, hi) * 2);
currentEnvironment
};

// "e { ... }" means that the function will always operate in this environment
~object.makeGui = {
~window = GUI.window.new("~object", Rect(10, 10, 200, 100));
~rangeSl = GUI.rangeSlider.new(~window, Rect(10, 10, 180, 20))
.action_(e { |view|
~lo = (view.lo * 20).asInteger;
~hi = (view.hi * 20).asInteger;
});
~fireButton = GUI.button.new(~window, Rect(10, 40, 180, 20))
.states_([["print number"]])
.action_(e {
~printRandom.();  // shortcut for ".value"
});
~window.front;
};


~object.printRandom;
~object.printRandom(25, 30);


Attachment: ddwPrototype.tar.gz
Description: GNU Zip compressed data


: H. James Harkins

: jamshark70@xxxxxxxxxxxxxxxxx

: http://www.dewdrop-world.net

.::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..:


"Come said the Muse,

Sing me a song no poet has yet chanted,

Sing me the universal."  -- Whitman