// title: Converting an environment in a prototype object // author: julian.rohrhuber // description: // /* // I often like to write out a library as an environment, like: // // ~start_sound = { |freq, amp| <...> }; // ~start_high_pitch_sound = { |amp| ~start_sound.(14000, amp) }; // // … and then use loadRelative to load that library. // // This, however has the problem that you can't stick the whole library into an environment that you call from the outside. e.g. // // q = (); // q.use { resolveRelative("/library.scd") }; // // and then trying: // // q.start_sound(700, 0.1); // q.start_high_pitch_sound(0.1); // // will not work. Firstly, it will expect the environment as first argument of each function, second, it won't find a function like ~start_sound from within the call context. // // Here is a way to convert an environment as needed. // // */ // code: ~constructPseudoMethods = { |envir| var newEnvir = envir.collect { |value| var argNames, argBlock, namesBlock, code, func; if(value.isKindOf(Function)) { func = value; argNames = func.def.argumentString(withDefaultValues: true); namesBlock = func.def.argumentString(withDefaultValues: false); argBlock = if(argNames.notNil) { "|self, " ++ argNames ++ "|" }; code = "{ |func, envir| { % envir.use { func.value(%) } } }".format(argBlock ? "", namesBlock ? ""); //code.postln; code.interpret.value(func, envir) } { value } }; newEnvir.know = true; // we want a prototype object style environment };