From the NannyMUD documentation

LAST CHANGE

2000-12-23

TOPIC

NAME

        class1 - A log from TMI, part 1.

DESCRIPTION

	This is part 1 of some logs from TMI, The MUD Institute, a MUD
	dedicated to teaching LPC. TMI has gone down since, and been replaced
	by TMI-II.

	Profezzorn says: ok, we go to mappings
	Profezzorn says: theory first, or examples?
	Tlofgren says: theory first, then examples. :)
	Profezzorn says: ok, mappings are ascosiative arrays
	Profezzorn says: if that is how it is spelled
	Tlofgren says: probably not, but I'm with ya
	Bwilliams nods solemnly.
	Profezzorn says: the idea is to make an array that can be indexed on 
			 anything
	Profezzorn says: in lpc the type is called mapping, and it is declared
			 like:
	Profezzorn says: mapping map;
	Profezzorn says: it is indexed just as an array:
	Profezzorn says: map[index]
	Tlofgren nods solemnly.
	Profezzorn says: where the index can be of any type
	Profezzorn says: when assigning to an index in a mapping
	Profezzorn says: map[index]=data
	Profezzorn says: the index will be added to the mapping if it doesn't
			 exist already
	Profezzorn says: so a mappign can grow when more data is assigned to it
	Bwilliams says: there is no allocate required for mappings?
	Profezzorn says: well, you have to init the array, but the size isn't
			 important
	Profezzorn says: the mapping I mean
	Profezzorn says: you init the mapping to an empty mapping like this:
	Profezzorn says: map=([]);
	Bwilliams nods solemnly.
	Profezzorn says: that is also how you write constant mappings
	Khan says: the question i have: how slow an memory expensiv is an
	           mapping against an usual lets say mixed * ????
	Profezzorn says: mapings are slower and use more memory, but the exact
			 values depends on the implementation
	Khan says: hmm
	Profezzorn says: amylaar mudos and 3.1.2 all have different
			 implementations
	Bwilliams nods solemnly.
	Profezzorn says: the way to write constant mappings is this:
	Profezzorn says: ([index1:data1,index2:data2,index3:data3 .... ])
	Profezzorn says: so if if I wrote
		map=([index1:data1,index2:data2,index3:data3]);
	Profezzorn says: and then map[index1] I would get data1
	Bwilliams says: is undefinedp(map["index"]) the standard on all
			drivers?
	Profezzorn says: no
	Profezzorn says: that is mudos specific I think
	Bwilliams nods solemnly.
	Bwilliams says: how do you check for existance of an index?
	Profezzorn says: when an index isn't present in a mapping, it normally
			 returns 0
	Khan nods solemnly.
	Profezzorn says: in mudos you can examine that 0 closer with
			 unefinedp() too see if it was a zero from a data in
			 the mapping, or a zero because the index wasn't there
	Profezzorn says: any questions so far?
	Khan says: no ..
	Tlofgren shakes and quivers like a bowlful of jelly.
	Bwilliams says: or use member_array(keys(map),"index") == -1
	Profezzorn says: keys is also mudos-specific
	Bwilliams sighs deeply.
	Bwilliams nods solemnly.
	Tlofgren says: what's w/ the different drivers?
	Tlofgren says: how different are they?
	Profezzorn says: in some areas they are very different
	Bwilliams says: that is a real topic!
	Profezzorn nods solemnly.
	Profezzorn says: however, the more 'standardized' way to get an array
			 of all indexes in an array is m_indices(map)
	Tlofgren says: ok, carry on then
	Khan says: hmm on 3.2.1... u could use m_indices(map) ??!
	Khan grins evilly.
	Profezzorn says: and m_values(map) to get an array of the values
	Bwilliams says: and on amylaar?
	Profezzorn says: amyaar use m_indices / m_values too
	Bwilliams says: where mudos uses keys() and values()
	Khan says: we have amylaar 03.02.1@22.284 ..
	Khan nods solemnly.
	Profezzorn says: mudos has m_indices and m_values too, as aliases for
			 keys and values
	Profezzorn says: it is vital to know that the arrays returned by
			 m_indices / m_values is indexed equally
	Bwilliams says: but somewhat randomly in MudOS
	Profezzorn says: that m_values(map)[e]=map[m_indices(map)[e]] for all
		e)
	Profezzorn says: it is vital to remember that m_delete isn't
			 destructive in all drivers
	Profezzorn says: on 3.1.2 it just returns a mapping with the index
			 deleted
	Profezzorn says: so you have to write map=m_delete(map,index);
	Profezzorn says: any questions?
	Bwilliams shakes and quivers like a bowlful of jelly.
	Profezzorn says: ok, let's move on to mkmapping()
	Tlofgren nods solemnly.
	Jngan nods solemnly.
	Profezzorn says: mkmaping does the opposite of m_indices and m_values
	Profezzorn says: ie. map is always equal to
			 mkmapping(m_indices(map),m_values(map))
	Bwilliams nods solemnly.
	Profezzorn says: ie. it creates a mapping from an array of index and
			 an array of values
	Tlofgren nods solemnly.
	Profezzorn says: then there are only 3 standard efuns connected to
			 mappings left
	Profezzorn says: mappingp(X) which returns 1 if X is a mapping
	Profezzorn says: and filter_mapping / map_mapping
	Profezzorn says: filter_mapping(map,function_name,object to call
			 function in,optional extra argument)
	Profezzorn says: that's the approximate syntad for filter_mapping
	Profezzorn says: if I write it like:
	Bwilliams says: like filter_array()
	Profezzorn says: filter_mapping(map,fun,ob,extra)
	Profezzorn says: it will be easier to describe
	Profezzorn says: yes, it works just like filter_array
	Bwilliams nods solemnly.
	Profezzorn says: it calls ob->fun(x,extra) for every value in the
			 mapping with x set to that value
	Khan says: sorry .. got to go
	Khan waves good-bye.
	Bwilliams waves good-bye.
	Khan says: bye
	Profezzorn waves good-bye.
	Khan just left the school.
	Tlofgren says: can you give an example of when to use filter_mapping?
	Tlofgren says: I don't really see the use at this time.
	Profezzorn says: hmm
	Profezzorn says: the use isn't very broad
	Tlofgren nods solemnly.
	Profezzorn says: but, let's say that you have a mapping which contains:
	Profezzorn says: ([ player_name : level ])
	Bwilliams says: oh, checking exits[] for existance of loaded rooms
	Profezzorn says: ie. it is indexed on the name, and contains the level
	Profezzorn says: and you want to extract all wizards
	Tlofgren nods solemnly.
	Profezzorn says: then you use filter mapping
	Tlofgren says: ah, ok
	Profezzorn says: filter_mapping and map_mapping has one big
			 disadvantage though
	Profezzorn says: they don't send the index (in this case the name) to
			 the function
	Profezzorn says: as you might have guessed, map_mapping works exactly
			 like filter_mapping, but it returns a mapping where
			 the values are those returned from the function
	Profezzorn says: hope you don't have problems with linebreak...
	Profezzorn smiles happily.
	Bwilliams says: I'm ffine
	Tlofgren says: I don't.
	Profezzorn says: any questions?
	Bwilliams says: what do they pass to the function if not the index?
	Profezzorn says: the value
	Bwilliams says: so you test the value for inclusion in the set,
			returning 1/0?
	Profezzorn says: yes
	Profezzorn says: in filter_array that is
	Profezzorn says: or do you mean the set of indexes
	Bwilliams says: the filter function returns true/false if the value is
		acceptable for the filter, right?
	Profezzorn says: yes
	Bwilliams says: what does map_mapping return?
	Profezzorn says: map_mapping(map,fun,ob) does the same as
		mkmapping(m_indices(map),map_array(m_values(map),fun,ob))
	Bwilliams says: /map_array/filter_mapping/ ?
	Ktaylor waves good-bye.
	Profezzorn says: are you asking if they are exchengable?
	Ktaylor just left the school.
	Bwilliams nods solemnly.
	Bwilliams sighs deeply.
	Profezzorn says: no, not really
	Profezzorn says: map_mapping(map,fun,ob) does the same as
		mkmapping(m_indices(map),map_array(m_values(map),fun,ob)),
		but faster
	Bwilliams nods solemnly.
	Profezzorn says: ok, as an example, I'll show a filter_mapping I just
			 coded in lpc
	Profezzorn says: varargs mapping filter_array(mapping m,
						      string fun,
						      object o,
						      mixed extra)
	Profezzorn says: {
	Profezzorn says:   mapping map;
	Profezzorn says:   int e;
	Profezzorn says:   mixed *a,*b;
	Profezzorn says:
	Profezzorn says:   map=([]);
	Profezzorn says:   a=m_values(m);
	Profezzorn says:   b=m_values(m);
	Profezzorn says:   for(e=0;efun must do a lookup of the
			index rather than operating on the value
	Bwilliams says: or a and b are the same array!
	Profezzorn says: I see that, a should be m_indices
	Profezzorn says: not m_values
	Bwilliams grins evilly.
	Tlofgren nods solemnly.
	Profezzorn says: here's another example
	Bwilliams says: and map[b[e]]=a[e] is reversed
	Profezzorn says: you're right :)
	Profezzorn says: I should write this in advance, but it's hard when
			 you don't know who's coming...
	Profezzorn says: :)
	Jngan smiles happily.
	Tlofgren nods solemnly.
	Profezzorn says: /* consider a shop that may sell 10 items / reset */
	Profezzorn says: mappign map;
	Profezzorn says: #define MAX 10
	Profezzorn says: void reset(int arg)
	Profezzorn says: {
	Profezzorn says: if(!arg) return;
	Profezzorn says: map=([]);
	Profezzorn says: }
	Profezzorn says: int sell(string what)
	Profezzorn says: {
	Profezzorn says: string name;
	Profezzorn says: /* some code to figure out things... */
	Profezzorn says: name=(string)this_player()->query_real_name();
	Profezzorn says: if(map[name]>MAX)
	Profezzorn says: {
	Profezzorn says: write("Come back later.\n");
	Profezzorn says: return 1;
	Profezzorn says: }
	Profezzorn says: map[name]++
	Profezzorn says: /* rest of sell code */
	Profezzorn says: }
	Tlofgren nods solemnly.
	Jngan nods solemnly.
	Profezzorn unloads the projector.
	Profezzorn puts something on the projector.
	Profezzorn says: another missing ; :)
	Profezzorn says: on line 20
	Tlofgren nods solemnly.
	Bwilliams says: 1s/mappign/mapping/ :)
	Profezzorn nods solemnly.
	Profezzorn says: any questions on this example?
	Tlofgren says: nope. :)
	Bwilliams says: that map[name]++ is a cute trick
	Tlofgren says: I agree.... useful
	Jngan nods solemnly.
	Profezzorn says: on some muds map[name]++ bugs a little, so writing
		map[name]=map[name]+1 might be wiser
	Profezzorn says: but that's just old muds
	Profezzorn says: the bug is that it doesn't become 1 if the index
			 doesn't exist, it becomes 2
	Profezzorn says: anyway, I would like to say something about mappings
			 and +
	Profezzorn says: mappings can be added with +
	Profezzorn says: which is very useful from time to time BUT
	Profezzorn says: indexes in mappings doesn't have to be unique
	Profezzorn says: when several data have the same index there is no way
			 of knowing which of those data you get by writing
			 map[index] 
	Bwilliams says: and you get only one?
	Profezzorn says: yes
	Profezzorn says: yes
	Profezzorn says: oops
	Bwilliams smiles happily.
	Tlofgren says: I think it's odd that they don't have to be unique...
		       can't see the use for having similar indexes...
	Profezzorn says: map[index]=data always keeps the indexes unique, as it
		assings over old data
	Tlofgren nods solemnly.
	Profezzorn says: but mkmapping() and + doesn't check that the indexes
			 are unique, they just do what they are told
	Tlofgren nods solemnly.
	Jngan nods solemnly.
	Bwilliams says: but map1+map2 can create duplicates
	Profezzorn says: yes
	Tlofgren says: yeah, true.
	Profezzorn says: if the same index is present in both map1 and map2,
			 the result will have two such index
	Profezzorn says: this differs a bit between the drivers though
	Profezzorn says: I think dgd checks and always make the indexes unique
	Jngan says: got an example?
	Bwilliams says: I know MudOS doesn't
	Profezzorn says: I know 3.1.2 doesn't
	Profezzorn says: anyway, I think we have covered how mappings
			 _should_ work now
	Bwilliams nods solemnly.
	Profezzorn says: in the advanced course I will cover how 3.1.2 mappings
			 can be used if you know what you're doing :)
	Profezzorn says: ie. implementation-specific stuff
	Profezzorn says: one last word though
	Profezzorn says: anothe prime use of mappings is to do binsort-like
			 things
	Profezzorn says: like if you want all objects with the same short()
	Tlofgren nods solemnly.
	Bwilliams snaps his fingers.
	Profezzorn says: then you loop over the array of objects, call short,
			 and put them into a mapping
	Profezzorn says: as we are out of time, how about doing that for
			 homework?
	Profezzorn grins evilly.
	Bwilliams grins evilly.
	Tlofgren says: heh
	Jngan giggles inanely.
	Tlofgren says: yeah, see you in a month. :P
	Profezzorn says: any homework submitted will get comments on efficiency
			 and coding style
	Profezzorn smiles happily.
	Bwilliams says: how do we submit homework?
	Tlofgren says: ok, thanks for the class. =)
	Profezzorn says: dunno yet :)
	Profezzorn says: we'll see about that next week
	Tlofgren waves good-bye.
	Profezzorn says: I'll try to have some examples on regexp() ready then
	Bwilliams nods solemnly.
	Jngan nods solemnly.
	Tlofgren says: gotta go to sleep. c ya
	Bwilliams says: I'll try to be here then....thanks for the info
	Jngan says: is there a place we can ftp for the log or something like
		    that?
	Profezzorn says: not yet