Skip to content

Commit 84ac8e1

Browse files
committed
Merge branch 'develop'
2 parents dc3adcc + 2d2f9e4 commit 84ac8e1

35 files changed

+1271
-917
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## v2.0.0 (March 14th, 2015)
2+
- Registered units of measure are now properties of PhysicalQuantity classes, and not individual instances of those classes. As such, registering a new unit with a given PhysicalQuantity will make that unit immediately available to all inntances of that class.
3+
- PhysicalQuantity classes no longer define their units in their constructor, and instead have a new initialize() static method
4+
- The previously-existing registerUnitOfMeasure() method on physical quantity objects has been replaced with a new static addUnit() method
5+
- The HasSoUnitsTrait method addMissingSIPrefixedUnits is now static
6+
- Added the toNativeUnit() method, to return values in their native unit of measure
7+
- Added the isEquivalentQuantity() method, to support future situations where it's not obvious whether two physical quantities represent the same quantity type
8+
- getSupportedUnits() is no longer available on physical quantities
9+
- The PhysicalQuantity parent class is now named AbstractPhysicalQuantity
10+
- Add a new DemonstrationTests test file, to demonstrate and test typical use cases
11+
- All library exceptions extend from AbstractPhysicalQuantityException, making catching easier
12+
- Added an interface for PhysicalQuantities, to support future work where not all physical quantity classes necessarily have the same parent
13+
14+
115
## v1.3.1 (August 23rd, 2014)
216
- Added information in the README about the new SI prefix units generation
317

README.md

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ function isTooTallToRideThisTrain( $height )
2222
return $height > 5;
2323
}
2424

25-
// Calling the function requires that you first convert whatever quantity you have into the expected units:
25+
// Calling the function requires that you first convert whatever quantity
26+
// you have into the expected units:
2627
isTooTallToRideThisTrain(2 / 0.3048);
2728
```
2829

@@ -64,7 +65,7 @@ echo $quantity; // '6 lbs'
6465
```
6566

6667
### Arithmetic Operators
67-
There's also support for addition and subtraction. The values of `PhysicalQuantity` objects are immutable, and so these arithmetic methods return new quantity objects representing the results:
68+
There's also support for addition and subtraction. The values of the physical quantity objects are immutable, and so these arithmetic methods return new quantity objects representing the results:
6869

6970
``` php
7071
use PhpUnitsOfMeasure\PhysicalQuantity\Volume;
@@ -91,35 +92,42 @@ To add a new unit of measure to an existing quantity at run time, you'd do this:
9192
use PhpUnitsOfMeasure\PhysicalQuantity\Length;
9293
use PhpUnitsOfMeasure\PhysicalQuantity\UnitOfMeasure;
9394

94-
// It's ok to use cubits here, since the conversion doesn't happen until later
95+
// It's ok to create objects with cubits before the new unit is registered, since
96+
// the conversion doesn't happen until an output method is called
9597
$length = new Length(14, 'cubits');
9698

97-
// Build a new Unit of Measure object which represents the new unit, and which knows how to convert between
98-
// the new unit and the quantity's native unit (in this case, meters).
99+
// Build a new Unit of Measure object which represents the new unit, and which
100+
// knows how to convert between the new unit and the quantity's native unit
101+
// (in this case, meters).
99102
$cubit = new UnitOfMeasure(
100103

101-
// This is the official name of this unit - typically it's the standard abbreviation
104+
// This is the official name of this unit - typically it's the standard
105+
// abbreviation
102106
'cb',
103107

104-
// The second parameter is a closure that converts from the native unit to this unit
108+
// The second parameter is a function that converts from the native unit
109+
// to this unit
105110
function ($valueInNativeUnit) {
106111
return $valueInNativeUnit / 0.4572;
107112
},
108113

109-
// The third parameter is a closure that converts from this unit to the native unit
114+
// The third parameter is a function that converts from this unit to the
115+
// native unit
110116
function ($valueInThisUnit) {
111117
return $valueInThisUnit * 0.4572;
112118
}
113119
);
114120

115-
// Any alias names for this unit can be added here, to make it easier to use variations
121+
// Any alias names for this unit can be added here, to make it easier to use
122+
// variations
116123
$cubit->addAlias('cubit');
117124
$cubit->addAlias('cubits');
118125

119-
// Register the new unit of measure with the quantity object
120-
$length->registerUnitOfMeasure($cubit);
126+
// Register the new unit of measure with the quantity class
127+
Length::addUnit($cubit);
121128

122-
// Now that the unit is registered, you can cast the measurement to any other measure of length
129+
// Now that the unit is registered, you can cast the measurement to any other
130+
// measure of length
123131
echo $length->toUnit('feet'); // '21'
124132
```
125133

@@ -130,42 +138,43 @@ Note that when creating instances of `UnitOfMeasure`, there are a couple of conv
130138
$megameter = UnitOfMeasure::linearUnitFactory('Mm', 1e6);
131139
$megameter->addAlias('Megameter');
132140
$megameter->addAlias('Megametre');
133-
$length->registerUnitOfMeasure($megameter);
141+
Length::addUnit($megameter);
134142
```
135143

136-
The other convenience method is a special case of the above scaling factor factory method where the scaling factor is set to exactly 1, and serves as a convenient way of generating the native unit of measure. All `PhysicalQuantity` classes must have one and only one native unit, so this method will probably only be called once per `PhysicalQuantity` class:
144+
The other convenience method is a special case of the above scaling factor factory method where the scaling factor is set to exactly 1, and serves as a convenient way of generating the native unit of measure. All physical quantities must have one and only one native unit, so this method will probably only be called once per Physical Quantity class:
137145

138146
``` php
139147
$meter = UnitOfMeasure::nativeUnitFactory('m');
140148
$meter->addAlias('meter');
141149
$meter->addAlias('metre');
142-
$length->registerUnitOfMeasure($meter);
150+
Length::addUnit($meter);
143151
```
144152

145153
##### Automatically Generating Metric Units
146-
For units that use the metric system, there's a convenience trait available for `PhysicalQuantity` classes which will automatically generate the full continuum of metric units from a single unit. For instance:
154+
For units that use the metric system, there's a convenience trait available for classes which implement`PhysicalQuantityInterface` which will automatically generate the full continuum of metric units from a single unit. For instance:
147155

148156
``` php
149157
namespace PhpUnitsOfMeasure\PhysicalQuantity;
150158

151-
use PhpUnitsOfMeasure\PhysicalQuantity;
159+
use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
152160
use PhpUnitsOfMeasure\UnitOfMeasure;
153161
use PhpUnitsOfMeasure\HasSIUnitsTrait;
154162

155-
class Mass extends PhysicalQuantity
163+
class Mass extends AbstractPhysicalQuantity
156164
{
157165
use HasSIUnitsTrait;
158166

159-
public function __construct($value, $unit)
160-
{
161-
parent::__construct($value, $unit);
167+
protected static $unitDefinitions;
162168

169+
protected static function initialize()
170+
{
171+
// Kilogram
163172
$kilogram = UnitOfMeasure::nativeUnitFactory('kg');
164173
$kilogram->addAlias('kilogram');
165174
$kilogram->addAlias('kilograms');
166-
$this->registerUnitOfMeasure($kilogram);
175+
static::addUnit($kilogram);
167176

168-
$this->addMissingSIPrefixedUnits(
177+
static::addMissingSIPrefixedUnits(
169178
$kilogram,
170179
1e-3,
171180
'%pg',
@@ -178,29 +187,29 @@ class Mass extends PhysicalQuantity
178187
}
179188
```
180189

181-
Here we're generating the native unit for mass, kilogram, adding it to the quantity as usual, and then using it to generate the spectrum of SI units by calling the `addMissingSIPrefixedUnits()` method provided by the `HasSIUnitsTrait` trait.
190+
Here we're generating the native unit for mass, kilogram, adding it to the quantity as usual, and then using it to generate the spectrum of SI units by calling the `addMissingSIPrefixedUnits()` static method provided by the `HasSIUnitsTrait` trait.
182191

183-
Of note, the second parameter (1e-3) is denoting that while kilograms are the native unit for Mass, there's a factor of 1/1000 between the kilogram and the base metric unit of mass: the gram. For units such as seconds or meters where the native unit for the `PhysicalQuantity` class is also the base unit for the metric prefix system, this factor would be 1.
192+
Of note, the second parameter (1e-3) is denoting that while kilograms are the native unit for Mass, there's a factor of 1/1000 between the kilogram and the base metric unit of mass: the gram. For units such as seconds or meters where the native unit for the physical quantity is also the base unit for the metric prefix system, this factor would be 1.
184193

185194
The 3rd and 4th parameters contain templates for the units' names and alternate aliases, respectively. The replacement strings '%p' and '%P' are used to denote the abbreviated and long-form metric prefixes. For instance, '%pg' would generate the series `..., 'mg', 'cg', 'dg', 'g', ...`, while the template '%Pgram' would generate the series `..., 'milligram', 'centigram', 'decigram', 'gram', ...` .
186195

187196
#### Permanently Adding a New Unit of Measure to a Physical Quantity
188-
The above method only applies to the specific instantiation of `Length` and is therefore temporary; it would be necessary to repeat this process every time you created a new `Length` object measurement and wanted to use cubits.
197+
The examples above for adding new units of measure to physical quantities allow you to register new units for the duration of the PHP execution, but are lost once execution terminates; it would be necessary to repeat this process every time you created a new program with `Length` measurements and wanted to use cubits.
189198

190-
A new unit of measure can be permanently added to a `PhysicalQuantity` class by essentially the same process, only it would be done inside the constructor of the quantity class. For example:
199+
A new unit of measure can be permanently added to a Physical Quantity class by essentially the same process as the one-time examples, only it would be done inside the initialize() method of the quantity class. For example:
191200

192201
``` php
193202
namespace PhpUnitsOfMeasure\PhysicalQuantity;
194203

195-
use PhpUnitsOfMeasure\PhysicalQuantity;
204+
use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
196205
use PhpUnitsOfMeasure\UnitOfMeasure;
197206

198-
class Length extends PhysicalQuantity
207+
class Length extends AbstractPhysicalQuantity
199208
{
200-
public function __construct($value, $unit)
201-
{
202-
parent::__construct($value, $unit);
209+
protected static $unitDefinitions;
203210

211+
protected static function initialize()
212+
{
204213
// ...
205214
// ...
206215
// Here's all the pre-existing unit definitions for Length
@@ -211,17 +220,17 @@ class Length extends PhysicalQuantity
211220
$cubit = UnitOfMeasure::linearUnitFactory('cb', 0.4572);
212221
$cubit->addAlias('cubit');
213222
$cubit->addAlias('cubits');
214-
$this->registerUnitOfMeasure($cubit);
223+
static::addUnit($cubit);
215224
}
216225
}
217226
```
218227

219-
Now any new object of class `Length` that gets instantiated will come with the cubits unit already built in. Note that here we used the more concise linear unit factory method, but the result is equivalent to the expanded form calling the constructor, as used above.
228+
Now any program which uses `Length` will start with the cubits unit already built in. Note that here we used the more concise linear unit factory method, but the result is equivalent to the expanded form calling the `UnitOfMeasure` constructor, as used above. Also, notice that the `static` keyword was used instead of the class name, though either would be acceptable in this case.
220229

221230
### Adding New Physical Quantities
222231
[Physical quantities](http://en.wikipedia.org/wiki/Physical_quantity) are categories of measurable values, like mass, length, force, etc.
223232

224-
For physical quantities that are not already present in this library, it will be necessary to write a class to support a new one. All physical quantities extend the `\PhpUnitsOfMeasure\PhysicalQuantity` class, and typically have only a constructor method which creates the quantity's units of measure. See above for examples on how to add new units to a quantity class.
233+
For physical quantities that are not already present in this library, it will be necessary to write a class to support a new one. All physical quantities implement the `\PhpUnitsOfMeasure\PhysicalQuantityInterface` interface, typically extend the `\PhpUnitsOfMeasure\AbstractPhysicalQuantity` class, and typically have only an `initialize()` method which creates the quantity's units of measure. See above for typical examples of physical quantity classes and of how to add new units to a quantity class.
225234

226235
Note that every physical quantity has a chosen "native unit" which is typically the SI standard. The main point for this unit is that all of the quantity's other units of measure will convert to and from this chosen native unit. It's important to be aware of a quantity's native unit when writing conversions for new units of measure.
227236

@@ -231,20 +240,23 @@ It may come up that the desired unit of measure exists for a given physical quan
231240
``` php
232241
use PhpUnitsOfMeasure\PhysicalQuantity\Length;
233242

234-
// It's ok to use footses here, since the conversion doesn't happen until later
243+
// It's ok to use footses here, since the conversion doesn't happen
244+
// until later
235245
$length = new Length(4, 'footses');
236246

237247
// Fetch the unit of measure object that represents the 'ft' unit
238-
$foot = $length->findUnitDefinition('ft');
248+
$footUnit = Length::getUnit('ft');
239249

240-
// Any alias names for this unit can be added here, to make it easier to use variations
241-
$foot->addAlias('footses');
250+
// Any alias names for this unit can be added here, to make it easier
251+
// to use variations
252+
$footUnit->addAlias('footses');
242253

243-
// Now that the unit is registered, you can cast the measurement to any other measure of length
254+
// Now that the unit has been modified with its new alias, you can cast
255+
// the measurement to any other measure of length
244256
echo $length->toUnit('m'); // '1.2192'
245257
```
246258

247-
And of course, if you need to add the alias permanently, you can do so in the constructor of the quantity's class.
259+
And of course, if you need to add the alias permanently, you can do so in the initialize() method of the quantity's class, as shown above.
248260

249261
## Testing and Contributing
250262
Pull requests are welcome, especially regarding new units of measure or new physical quantities. However, please note that there are many sources for conversion factors, and not all are careful to respect known precision.

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
},
2828

2929
"require": {
30-
"php": ">=5.3.5"
30+
"php": ">=5.4.0"
3131
},
3232

3333
"require-dev": {
34-
"phpunit/phpunit": "4.2.*",
35-
"squizlabs/php_codesniffer": "1.5.*"
34+
"phpunit/phpunit": "4.4.*",
35+
"squizlabs/php_codesniffer": "2.0.*"
3636
},
3737

3838
"autoload": {

0 commit comments

Comments
 (0)