1.3.0◀Back | Minified | Changelog | Cautionlog
v1.3.0 is out! This one has been a long time in the waiting and has some really nice changes.
Sugar just got a lot more customizable. The "core" package is now split by class, meaning you can now create custom Sugar builds that include only the specific classes you need. Date locales have also been moved out of the default and into their own package, as have other language-specific methods, helping to push down the default download size to just under 16kb. This process represents a major refactoring and makes Sugar now extremely modular.
Additionally, the ECMAScript shim methods (browser built-in methods like
Array#indexOf for browsers that don't support like IE) are now moved out into their own package as well. If you don't require legacy browser support (typically IE8 and below), you can remove this package and immediately save 1kb.
Sugar custom packages can be built here.
Enumerable Object Methods
each method. This update now provides 14 new array methods to also now work on objects as well. These methods are:
Sugar of course never modifies
Object.prototype, so these methods all exist as class methods. However, they are also available to extended objects, making them nearly as powerful as true Ruby-style hashes for a little extra work up front. This is especially evident when storing and manipulating JSON data:
Note that when callbacks are passed to enumerable methods, where they would previously be passed
element, index for arrays, they are now instead passed
key, value as the first 2 arguments. Last argument and
this keyword is still the object itself.
Also of note is that these methods (as well as
isEmpty) now reside in the Array package (which can be thought of as the "Enumerables" package), which means that they won't be available without including that package.
Finally, a single method
Object.size was added as a shortcut to get the number of members in an object. "Size" was chosen as it is distinct from
length, which is not a method, but a property.
A new concept for Sugar, "date ranges", as the name implies, are an object that define a specific range of time with a discernable start and end. They are created through the Date class by simply passing a start and end to
Date.range, which understands anything that
All of these will result in valid ranges (note that if an argument is falsy it is assumed to be the current time). Once created, these ranges can be iterated over in various ways:
In the examples above, callback
fn will be passed a date object for each unit within the range, and will return an array containing every date object that was visited. Important to note is that the string format
"2 weeks", and the
each shortcuts, which are equivalent, reset lower units and increment that unit directly. This means that
every("day") on a range starting at
June 27th 4:25pm will first visit
June 27th 12:00:00am and increment the
date by 1 on every iteration. In contrast,
every((1).day()), which is receiving a number in milliseconds, will begin at
June 27th 4:25pm and increment the date by 86400000 milliseconds on every iteration. Passing a number is more useful when precision is required.
Ranges also have a few other useful methods like
contains which will determine if the range contains a date or another date range. Ranges can also be manipulated with
union which act much like their Array counterparts. Of note, however, is that Date Ranges only have a single start and end, so any gaps in 2 ranges that have been merged will effectively be "filled in".
Date Ranges reside in their own package, which is included in the default download. For a full method list, see the docs.
A lot of updates have gone into the Date class, including some good performance optimizations. Date parsing formats are now scoped to their respective locale. Previously, when a language was set, its formats were added globally. While this did allow formats to be parsed without the proper locale code passed, it was a large performance penalty. This has now been changed so that the locale must be set correctly (either globally or by passing it to the date creation methods), however once set, the number of formats to lookup is significantly smaller, making for a faster result. Formats that are language-agnostic (such as numeric formats) are common to all locales.
This update also added the concept of a "cached format", which will take the last format that was successfully parsed and front load it, making operations that parse the same format repeatedly much faster.
Date output also has been enhanced, with 3 new output formats added for each locale:
short is the date alone,
long is the date and time, and
full is the full date and time with weekday and seconds. All 3 are available both through
format, and as instance shortcut methods and can be passed locale codes returning formats appropriate to their given locale:
The default format for
Date.format() is now the
Date manipulation also got some polishing.
Date#reset will now accept any unit, for example
date.reset('day') will reset the date and all smaller units. This method replaces
Date#resetTime, which is now deprecated.
Date#advance will now accept a string format like
"4 days", and, along with advancing methods like
Date#addDays, now accepts a 2nd boolean argument which will reset all units lower than the one being passed, similar to
Another cool addition is
Date.future, which are alternate forms of
Date.create. They will similarly parse a date, but will assume past or future when there is ambiguity, allowing the parsing system to infer context that was previously impossible:
A good use for these methods would be a commenting system where such ambiguities are always in the past, or conversely a to-do list, where they are always in the future.
Date parsing now also handles a lot more formats. Time parsing is now much more robust and is fully supported in all locales, and includes time strings both before and after their corresponding date formats. Some pretty cool features like being able to parse out Chinese character numerals as numbers in dates and localized
<date> at <time> formats are now supported as well.
Timezone issues also got a long looking at and a number of issues, especially those dealing with traversing across DST (daylight savings time) have now been addressed.
Other date changes include:
- Added the format
- Added the format
in 3 days, etc.
- Added the format
the 2nd Tuesday of November, etc.
- Added formats
next <weekday>in all locales
- Passing locales codes like "it_IT" will now fall back to just
itbefore bailing out.
- Unknown languages codes in
Date.createwill simply return invalid instead of throwing an error.
- Added support for time suffixes in Asian time strings ("時" etc)
- Various other fixes
Math are now mapped to
Number, making them easily accessible. This previously included
round, (all of which take a value for precision), but now includes
log. Note that the
base parameter for
log defaults to
Math.E, returning the natural log of the number.
String#namespaceis now moved into the main String package, which takes a period-separated string and finds the corresponding namespace, by default starting from the global namespace.
String#normalizenow lives in the "Language" package instead of the "Inflections" package.
- Script detection methods (
String#hasHangul, etc.) are likewise moved into the "Language" package.
String#katakanaare also moved to the "Language" package.
String#split, which was added as a patch for discrepancies when splitting strings on regexes is now moved out of the main build and into
lib/extra/in the repo. Although useful, this patch was simply using up too much space to justify such an edge-case requirement. It also did not fit neatly into any packages, and so is being moved out.
Array#hasis deprecated. Use
Array#groupByno longer returns extended objects, and is fixed to no longer corrupt array lengths.
- Enumerable array methods are now fixed to fuzzy match instances of classes as well as plain objects.
String#capitalizenow capitalizes after all special characters, not just after spaces.
String#insertnow treats negative indexes like
- Fixed issue with