View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

Strings and Streams and Post

An informal tutorial on strings and how they use streams
(sc2)

nb. in SC3 there is an object archive system. there may or may
not be issues of breakability with that archive if you alter the class
definition.
with the save/load system described below there is always an issue
of breakability because your .asCompileString must match up to your constructor.
but on the other hand, you can save only relevant information, not archive the
complete interior state of the object.
so each method has its pros and cons for a given application.

related: stream Patterns as compileString, a class extension for streaming patterns (sc3)



An informal tutorial on strings and streams

// how to save objects to disk...
(
var a;

a=Array.fill(rrand(2,8),{ Array.fill(rrand(2,8),{Array.fill(rrand(2,8),{10.0.rand })})});

// this is the simplest, but it prints on one long line which will run into problems...
a.asCompileString.write("test");


)


(
var a;

a=Array.fill(rrand(2,8),{ Array.fill(rrand(2,8),{Array.fill(rrand(2,8),{10.0.rand })})});

/**
	String.streamContents creates a new string and allows you to stream to it..
	or from it.
	this produces the same as the above example.

**/
b=String.streamContents
	({arg stream;

		stream <<< a 		// shorthand for storeOn
		
	});
	
b.write("test");

)

(
// Post creates a stream and posts it when you're done with it;
// I use it here just to demonstrate the use of << etc.

//  In all cases where you are given a stream as an argument
// you can use the same shorthand to send stuff to it.

Equivalent :

(
	var s;
	s=String.streamContents({arg stream;
		stream <<< "this is a string";
	});
	
	s.postln;
	
"this is a string"

)

(
	var s;
	s=String.streamContents({arg stream;
		"this is a string".storeOn(stream);
	});
	
	s.postln;
	
"this is a string"

)

(

	Post <<< "this is a string"

"this is a string"

)


// "string".storeOn(stream)   or stream <<< "string"	
Post <<<	"this is a string with storeOn";	
"this is a string with storeOn"

// string.printOn(stream) or stream << "string"
Post << "this is a string with printOn";
this is a string with printOn

Post <<< 'this is a symbol with storeOn';
'this is a symbol with storeOn'

Post << 'this is a symbol with printOn';
this is a symbol with printOn

Post <<< [\eins,\zwei,\drei,\vier];
[ 'eins', 'zwei', 'drei', 'vier' ] 
 
Post << [\uno , \dos, \tres, \quatros];
[ uno, dos, tres, quatros ]


// storeItemsOn and printItemsOn stores the contents,
// appropriately laid out with commas between them,
// but not the (array) object itself.


// printItemsOn
Post <<* [\eesh, \mee, \sun, \shi];  // i am  sorry japan !
eesh, mee, sun, shi

// storeItemsOn
Post <<<* [\one, \two];
'one', 'two'
 
 
 
  
)	





// String.streamContents
(
var a;

a=Array.fill(rrand(2,8),{ Array.fill(rrand(2,8),{Array.fill(rrand(2,8),{10.0.rand })})});

/**
	streamContents creates a new string and allows you to stream to it..
	or from it.

**/

b=String.streamContents
	({arg stream;
		
		stream << "[";
		stream.nl;
		
							// using the named method storeItemsOn allows you to specify
		a.storeItemsOn(stream,1); //  a limit of items per line
		stream.nl;
		stream << "]"			// but you have to put your own [ ] in.   ( or #[ ] )
	});

// b is now a string
b.write("test");


Post <<< b;


"[
[ [ 1.17906, 0.846289, 0.86935 ], [ 4.8054, 9.79029, 7.88911, 7.56603, 3.48827, 7.91247, 3.40114 ], [ 6.76641, 8.4192, 4.35059, 0.546304, 8.95122 ], [ 0.476807, 8.89619, 6.22702, 6.76312 ], [ 9.3701, 4.77664, 6.4156, 0.351985, 0.148747, 5.08866, 0.585393, 4.22134 ], [ 0.102574, 9.95051, 6.71261, 4.59483, 7.34807, 6.32625 ], [ 9.56817, 7.73468, 2.86842, 2.44443, 3.99737, 6.14813, 2.76293 ] ], 
  [ [ 1.5095, 5.93296, 4.02759, 2.78351, 6.4536 ], [ 6.42929, 2.40051, 9.28272, 0.594436, 6.55608, 3.29845 ], [ 6.35394, 9.60185, 5.86281, 1.5425 ] ], 
  [ [ 9.18442, 5.97908, 1.43937, 4.95201, 5.51559, 5.64771, 8.90351, 2.38679 ], [ 7.07015, 8.27813, 3.13926, 2.14918, 5.69124, 2.26382 ] ], 
  [ [ 8.13535, 1.61002, 7.17724, 8.09508, 7.98826 ], [ 3.08367, 3.40262, 0.260652, 4.09779, 7.76573, 6.5423 ], [ 7.73582, 8.35246, 6.39651 ], [ 9.86232, 9.24771 ] ], 
  [ [ 3.19182, 5.86613, 9.43917, 4.09425, 1.14278, 6.19137, 0.758039 ], [ 9.07598, 4.06283, 9.91185, 1.81059, 8.08178, 0.597169, 4.78998 ], [ 5.84739, 2.65083, 7.6451, 3.57966 ], [ 9.72982, 3.35794, 2.64053 ], [ 3.25305, 3.29775, 7.2532, 9.60902, 4.57537 ], [ 4.54883, 8.68868, 0.676669, 4.86076, 3.18845, 5.8161, 8.92322 ], [ 7.40658, 3.89509, 4.80755, 2.28617, 4.4239, 2.36471, 9.07311 ], [ 7.8854, 7.83216, 3.12985, 0.240976, 2.48011 ] ], 
  [ [ 0.934954, 7.39874, 7.88826, 3.87052 ], [ 8.78547, 1.97463, 7.14716, 5.39136, 3.84014, 4.13065, 9.76883, 3.38001 ], [ 5.03856, 6.336, 0.388697 ], [ 5.02804, 2.47092, 0.00821674, 9.32612, 4.89461, 7.64534, 7.18178, 1.28648 ], [ 7.54932, 2.43658, 7.5394, 8.77341, 7.40727, 3.42985 ] ], 
  [ [ 0.147479, 4.59053, 4.18441, 1.53558 ], [ 8.13799, 3.40451, 4.03556, 1.24931, 2.25888, 8.49044 ], [ 1.08721, 4.72348, 0.122623, 1.56294, 4.57369, 2.72276, 6.27432, 9.38852 ], [ 2.20728, 3.30596, 1.15425, 4.09404 ], [ 0.741168, 5.41698, 3.43556 ] ]
]"

)




( // reading in ....
var b;

b=thisProcess.interpreter.executeFile("test");



// after a bit this prints "...etc..."
b.postln;
// etc...
[ [ [ 1.17906, 0.846289, 0.86935 ], [ 4.8054, 9.79029, 7.88911, 7.56603, 3.48827, 7.91247, 3.40114 ], [ 6.76641, 8.4192, 4.35059, 0.546304, 8.95122 ], [ 0.476807, 8.89619, 6.22702, 6.76312 ], [ 9.3701...etc...




// use this to see the whole thing
Post <<< b;
// all on one line
[ [ [ 1.17906, 0.846289, 0.86935 ], [ 4.8054, 9.79029, 7.88911, 7.56603, 3.48827, 7.91247, 3.40114 ], [ 6.76641, 8.4192, 4.35059, 0.546304, 8.95122 ], [ 0.476807, 8.89619, 6.22702, 6.76312 ], [ 9.3701, 4.77664, 6.4156, 0.351985, 0.148747, 5.08866, 0.585393, 4.22134 ], [ 0.102574, 9.95051, 6.71261, 4.59483, 7.34807, 6.32625 ], [ 9.56817, 7.73468, 2.86842, 2.44443, 3.99737, 6.14813, 2.76293 ] ], [ [ 1.5095, 5.93296, 4.02759, 2.78351, 6.4536 ], [ 6.42929, 2.40051, 9.28272, 0.594436, 6.55608, 3.29845 ], [ 6.35394, 9.60185, 5.86281, 1.5425 ] ], [ [ 9.18442, 5.97908, 1.43937, 4.95201, 5.51559, 5.64771, 8.90351, 2.38679 ], [ 7.07015, 8.27813, 3.13926, 2.14918, 5.69124, 2.26382 ] ], [ [ 8.13535, 1.61002, 7.17724, 8.09508, 7.98826 ], [ 3.08367, 3.40262, 0.260652, 4.09779, 7.76573, 6.5423 ], [ 7.73582, 8.35246, 6.39651 ], [ 9.86232, 9.24771 ] ], [ [ 3.19182, 5.86613, 9.43917, 4.09425, 1.14278, 6.19137, 0.758039 ], [ 9.07598, 4.06283, 9.91185, 1.81059, 8.08178, 0.597169, 4.78998 ], [ 5.84739, 2.65083, 7.6451, 3.57966 ], [ 9.72982, 3.35794, 2.64053 ], [ 3.25305, 3.29775, 7.2532, 9.60902, 4.57537 ], [ 4.54883, 8.68868, 0.676669, 4.86076, 3.18845, 5.8161, 8.92322 ], [ 7.40658, 3.89509, 4.80755, 2.28617, 4.4239, 2.36471, 9.07311 ], [ 7.8854, 7.83216, 3.12985, 0.240976, 2.48011 ] ], [ [ 0.934954, 7.39874, 7.88826, 3.87052 ], [ 8.78547, 1.97463, 7.14716, 5.39136, 3.84014, 4.13065, 9.76883, 3.38001 ], [ 5.03856, 6.336, 0.388697 ], [ 5.02804, 2.47092, 0.00821674, 9.32612, 4.89461, 7.64534, 7.18178, 1.28648 ], [ 7.54932, 2.43658, 7.5394, 8.77341, 7.40727, 3.42985 ] ], [ [ 0.147479, 4.59053, 4.18441, 1.53558 ], [ 8.13799, 3.40451, 4.03556, 1.24931, 2.25888, 8.49044 ], [ 1.08721, 4.72348, 0.122623, 1.56294, 4.57369, 2.72276, 6.27432, 9.38852 ], [ 2.20728, 3.30596, 1.15425, 4.09404 ], [ 0.741168, 5.41698, 3.43556 ] ] ]



// or as it is an array, use the printItemsOn to print the contents
// and specify the number of items per line
b.printItemsOn(Post,1)


[ [ 1.17906, 0.846289, 0.86935 ], [ 4.8054, 9.79029, 7.88911, 7.56603, 3.48827, 7.91247, 3.40114 ], [ 6.76641, 8.4192, 4.35059, 0.546304, 8.95122 ], [ 0.476807, 8.89619, 6.22702, 6.76312 ], [ 9.3701, 4.77664, 6.4156, 0.351985, 0.148747, 5.08866, 0.585393, 4.22134 ], [ 0.102574, 9.95051, 6.71261, 4.59483, 7.34807, 6.32625 ], [ 9.56817, 7.73468, 2.86842, 2.44443, 3.99737, 6.14813, 2.76293 ] ], 
  [ [ 1.5095, 5.93296, 4.02759, 2.78351, 6.4536 ], [ 6.42929, 2.40051, 9.28272, 0.594436, 6.55608, 3.29845 ], [ 6.35394, 9.60185, 5.86281, 1.5425 ] ], 
  [ [ 9.18442, 5.97908, 1.43937, 4.95201, 5.51559, 5.64771, 8.90351, 2.38679 ], [ 7.07015, 8.27813, 3.13926, 2.14918, 5.69124, 2.26382 ] ], 
  [ [ 8.13535, 1.61002, 7.17724, 8.09508, 7.98826 ], [ 3.08367, 3.40262, 0.260652, 4.09779, 7.76573, 6.5423 ], [ 7.73582, 8.35246, 6.39651 ], [ 9.86232, 9.24771 ] ], 
  [ [ 3.19182, 5.86613, 9.43917, 4.09425, 1.14278, 6.19137, 0.758039 ], [ 9.07598, 4.06283, 9.91185, 1.81059, 8.08178, 0.597169, 4.78998 ], [ 5.84739, 2.65083, 7.6451, 3.57966 ], [ 9.72982, 3.35794, 2.64053 ], [ 3.25305, 3.29775, 7.2532, 9.60902, 4.57537 ], [ 4.54883, 8.68868, 0.676669, 4.86076, 3.18845, 5.8161, 8.92322 ], [ 7.40658, 3.89509, 4.80755, 2.28617, 4.4239, 2.36471, 9.07311 ], [ 7.8854, 7.83216, 3.12985, 0.240976, 2.48011 ] ], 
  [ [ 0.934954, 7.39874, 7.88826, 3.87052 ], [ 8.78547, 1.97463, 7.14716, 5.39136, 3.84014, 4.13065, 9.76883, 3.38001 ], [ 5.03856, 6.336, 0.388697 ], [ 5.02804, 2.47092, 0.00821674, 9.32612, 4.89461, 7.64534, 7.18178, 1.28648 ], [ 7.54932, 2.43658, 7.5394, 8.77341, 7.40727, 3.42985 ] ], 
  [ [ 0.147479, 4.59053, 4.18441, 1.53558 ], [ 8.13799, 3.40451, 4.03556, 1.24931, 2.25888, 8.49044 ], [ 1.08721, 4.72348, 0.122623, 1.56294, 4.57369, 2.72276, 6.27432, 9.38852 ], [ 2.20728, 3.30596, 1.15425, 4.09404 ], [ 0.741168, 5.41698, 3.43556 ] ]
  
  
// note that it prints the contents, without the surrounding top level [ ]   
  
  
  )
  
  
  
  
 .storeParamsOn
  
 at the most basic level
 Object::asCompileString says...
 	
 	asCompileString {
		_ObjectCompileString // in certain cases the primitive here will handle things and never return
		^String.streamContents({ arg stream; this.storeOn(stream); });	// but usually it does this
	}
	
	printOn { arg stream;
		var title;
		
		title = this.class.name.asString;
		stream << if((title @ 0).isVowel, { "an " }, { "a " }) << title ; 	
	}
	
		/** 
			 personally I preferred the old system that said  
			 	eg. Instance of String {    (01F53008, gc=80, fmt=08, flg=81, set=00) }
			that helped with spotting mistakes better.  (eg: oh ! it is a new array)
		**/
		
	storeOn { arg stream;
		var title;
		stream << this.class.name << ".new";
		this.storeParamsOn(stream);
		this.storeModifiersOn(stream);
	}
 
 	storeParamsOn { arg stream;
	}
	storeModifiersOn { arg stream;
	}

	so here any object will print its class name ++ ".new" :
	then call storeParamsOn which gives:
	
	Pseq.new(Array.rand(16,20,100),inf,0).asCompileString.postln;
	
Pseq.new
  
 //because there is not yet a storeParamsOn method written
  
 // but if you write just one method...
  
Pseq : ListPattern {
	var <>offset;
	*new { arg list, repeats=1, offset=0;
		^super.new(list, repeats).offset_(offset)
	}
	asStream { 
		^Routine.new({ arg inval;
			var item, offsetValue;
			offsetValue = offset.value;
			if (inval.eventAt('reverse') == true, {
				repeats.value.do({ arg j;
					list.size.reverseDo({ arg i;
						item = list @@ (i + offsetValue);
						inval = item.embedInStream(inval);
					});
				});
			},{
				repeats.value.do({ arg j;
					list.size.do({ arg i;
						item = list @@ (i + offsetValue);
						inval = item.embedInStream(inval);
					});
				});
			});
		});
	}
	
	storeParamsOn { arg stream;
		stream << "(";
		[list ,repeats,offset].storeItemsOn(stream);
		stream << ")"
	}
	
		
}



// you get...

	Pseq.new(Array.rand(16,20,100),inf,0).asCompileString.postln;

Pseq.new([ 75, 41, 47, 91, 37, 31, 43, 89, 75, 38, 
  85, 69, 66, 64, 68, 51 ],inf,0)


	... and you could save that to disk.
	
	If you write all the methods for the patterns
	you get all the modern conviences of save and load.
	
	eg. write it for your top level pattern (perhaps a Ppar:
	
	storeParamsOn { arg stream;
		stream << "(";
		list.storeItemsOn(stream,1); 
		stream << ")";
	}
	
	which would store all the (perhaps) Pbind in your list:
	
	storeParamsOn { arg stream; 
		
		stream << "(";
		patternpairs.storeItemsOn(stream,1);
		stream <<  ")";
	}
	
	etc. down the chain.
	
	Just ask the Ppar at the top to asCompileString itself, and .write(path) that to disk.
	
	Voila. now you can save the typing for expressing profound
	concepts rendered in code structures, rather than attempting
	to type out little melodies....
	



(http://www.crucial-systems.com)
7.5.00

Links to this Page