Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] [tuple version build round] Tuple tricks, build numbers, and rounding

From: gregg::pointillistic::com at: 27-Apr-2007 10:13

Tuples are an interesting datatype. They aren't a series, but you can use LENGTH?, PICK, POKE, and path notation, on them. Each segment is limited to a value of 255 (one byte) and you are limited to 10 segments in a tuple. If you assign a value greater than 255 to a segment, it becomes 255; a negative value becomes 0; no errors are thrown in either case. This makes them somewhat flexible, yet somewhat frustrating, but still very useful. If you add two tuples, the result is the length of the longer of the two, which can be very handy, as seen in the function below. Here, I want to use a tuple as a version number, with the first three segments being Major, Minor, and Revision; the last two being the build number. Originally I was going to use just one segment for the build number, but that limits you to 255 builds and, probably, an auto-incrementing revision number, which I didn't want. ; Convert an integral build number--a build counter--to the last ; two segments of a five segment version tuple. A single segment ; only gives us 255 builds before stepping into the third segment, ; which is usually the revision. If you want to force the revision ; number to step every 255 builds, use a four segement tuple base. set-build-num: func [tuple [tuple!] build [integer!]] [ tuple: tuple + 0.0.0.0.0 ; ensure we have five segments in our base tuple tuple/4: round/down build / 255 tuple/5: remainder build 255 tuple ] For display purposes, I don't necessarily want to show the full version to the end user (though that may be preferred in some cases). So, how do you go about keeping just part of a tuple? You can't use COPY/PART, because they aren't series! values, and you can't just assign 0 to the trailing segments, because they'll still show up. What you need to do is build a new tuple, using just the parts you want. This function does that, using my COLLECT function (available on REBOL.org) to keep the body to one line. round-tuple: func [ "Round a tuple to the given number of segments, truncating the rest." tuple [tuple!] scale [integer!] "The number of segments to keep" ][ to tuple! collect n [repeat i min scale length? tuple [n: tuple/:i]] ] This logic differs from the default algorithm for ROUND; this truncates, which is the same as ROUND/DOWN. I didn't like TRUNCATE-TUPLE or CHOP-TUPLE as names, but I'm not sure if having round in the name will be somewhat confusing. And I don't think it makes sense to round tuples in the same sense as rounding other values; I think it makes sense to always truncate them. I'd like to hear your thoughts an suggestions, and see what tuple tricks you all have up your sleeves. -- Gregg