Self-interpreting data works for the programmer
How often do you use text configuration files like ini, cfg, rc, xml, properties? Do you write handlers for them that parse strings and interpret commands?
And I propose otherwise - to write configurations in a scripting language (PHP, JavaScript, etc.), using the convenience of object-oriented programming.
Suppose the banners.ini file contains information about the banners that need to be displayed on the web page: As a rule, in this case, you need to read the data, check for correctness, parse it and put it into an array for further processing. So why not immediately write the same data as a finished array? The code has not been lost in the visualization, but now the input file does not need to be parsed! However, this is not all. If you go further, you can immediately determine the behavior of an object in the same file by assigning it a handler class. In the meantime, the FlashBanner and ImageBanner child classes will describe how these types of banners differ when displayed on the page. Moreover, now instead of ifs and switches for property analysis there will be only one call to the virtual method.
After that, all the “processing” of the configuration file is reduced to a couple of lines:
And in our projects, self-interpreting files that describe the database configuration play a special role. Having connected such a configuration file, we immediately get a class hierarchy for all tables with all fields, and each field, inheriting one of the standard classes IntField, StringField, DateField, etc., will automatically acquire methods for formatting, for checking for correct input, for links to other tables, etc.
Data in a self-interpreting form does not have to be presented manually, and, of course, the data processing language can be anything, including machine code. At the previous work, we used a rather interesting way to optimize the font storage format for the quickest possible display of text on the screen. Each letter of the font was compiled into a set of machine instructions, drawing a point or line in the desired position. As a result, the C code for the output of the line looked something like this:
Representation of the data in the form of executing constructions of the programming language allows us to significantly simplify the processing of this data without loss of visibility, saving on checking the correctness and analysis of the constructions (which the translator of the programming language itself performs), as well as on interpreting the data and connecting the description with the behavior.
PS And those interested in the work of a web programmer are welcome here - habrahabr.ru/job/2277
And I propose otherwise - to write configurations in a scripting language (PHP, JavaScript, etc.), using the convenience of object-oriented programming.
Example 1
Suppose the banners.ini file contains information about the banners that need to be displayed on the web page: As a rule, in this case, you need to read the data, check for correctness, parse it and put it into an array for further processing. So why not immediately write the same data as a finished array? The code has not been lost in the visualization, but now the input file does not need to be parsed! However, this is not all. If you go further, you can immediately determine the behavior of an object in the same file by assigning it a handler class. In the meantime, the FlashBanner and ImageBanner child classes will describe how these types of banners differ when displayed on the page. Moreover, now instead of ifs and switches for property analysis there will be only one call to the virtual method.
[Roga-Kopyta]
type = flash
width = 100
height = 100
src = roga-kopyta.swf
link = www.roga-kopyta.com
[SuperPuper]
type = image
width = 468
height = 60
src = superpuper.jpg
link = www.supper-pupper.net
$banners = array(
// Roga-Kopyta
array("type" => "flash",
"width" => 100,
"height" => 100,
"src" => "roga-kopyta.swf",
"link" => "http://www.roga-kopyta.com"),
// SuperPuper
array("type" => "image",
"width" => 468,
"height" => 60,
"src" => "superpuper.jpg",
"link" => "http://www.supper-pupper.net")
);
$banners[] = new FlashBanner(100, 100, "roga-kopyta.swf",
"http://www.roga-kopyta.com");
$banners[] = new ImageBanner(468, 60, "superpuper.jpg",
"http://www.supper-pupper.net");
abstract class Banner {
protected $width, $height, $src, $link;
public function __construct($width, $height, $src, $link) {
...
}
public function display() {
$html = $this->toHTML();
...
}
abstract public function toHTML();
}
class ImageBanner extends Banner {
public function toHTML() {
return "
"width={$this->width} height={$this->height}'>";
}
}
class FlashBanner extends Banner {
public function toHTML() {
return "";
}
}
After that, all the “processing” of the configuration file is reduced to a couple of lines:
include "banners.php";
foreach ($banners as $banner) {
$banner->display();
}
Example 2
And in our projects, self-interpreting files that describe the database configuration play a special role. Having connected such a configuration file, we immediately get a class hierarchy for all tables with all fields, and each field, inheriting one of the standard classes IntField, StringField, DateField, etc., will automatically acquire methods for formatting, for checking for correct input, for links to other tables, etc.
class Table_users extends Table {
function __construct {
$this->fields["id"] = new users_id();
$this->fields["login"] = new users_login();
$this->fields["password"] = new users_password();
$this->fields["group"] = new users_group();
$this->fields["registred"] = new users_registred();
}
}
class users_id extends IntField {
public $flags = BasicField::PRIMARY_KEY;
}
class users_login extends StringField {
public $size = 50;
}
class users_password extends StringField {
public $size = 255;
}
class users_group extends IntField {
public $foreignTable = "groups";
public $foreignKey = "id";
}
class users_registred extends DateField {
public $format = "d/m/Y";
}
...
class StringField extends BasicField {
public function validate($value) {
return is_string($value) && strlen($value) <= $this->size;
}
public function toHTML($value) {
return htmlspecialchars($value);
}
}
class DateField extends BasicField {
public function validate($value) {
...
}
public function toHTML($value) {
return date($this->format, $value);
}
}
Example 3
Data in a self-interpreting form does not have to be presented manually, and, of course, the data processing language can be anything, including machine code. At the previous work, we used a rather interesting way to optimize the font storage format for the quickest possible display of text on the screen. Each letter of the font was compiled into a set of machine instructions, drawing a point or line in the desired position. As a result, the C code for the output of the line looked something like this:
for (char* c = str; *c != 0; c++) {
x += font[*c](x, y);
}
Conclusion
Representation of the data in the form of executing constructions of the programming language allows us to significantly simplify the processing of this data without loss of visibility, saving on checking the correctness and analysis of the constructions (which the translator of the programming language itself performs), as well as on interpreting the data and connecting the description with the behavior.
PS And those interested in the work of a web programmer are welcome here - habrahabr.ru/job/2277