function set_rule($rules)
    {

        // continue only if argument is an array
        if (is_array($rules))

            // iterate through the given rules
            foreach ($rules as $rule_name => $rule_properties) {

                // make sure the rule's name is lowercase
                $rule_name = strtolower($rule_name);

                // if custom rule
                if ($rule_name == 'custom')

                    // if more custom rules are specified at once
                    if (is_array($rule_properties[0]) && count($rule_properties[0]) >= 3)

                        // iterate through the custom rules
                        // and add them one by one
                        foreach ($rule_properties as $rule) $this->rules[$rule_name][] = $rule;

                    // if a single custom rule is specified
                    // save the custom rule to the "custom" rules array
                    else $this->rules[$rule_name][] = $rule_properties;

                // for all the other rules
                // add the rule to the rules array
                else $this->rules[$rule_name] = $rule_properties;

                // for some rules we do some additional settings
                switch ($rule_name) {

                    // we set a reserved attribute for the control by which we're telling the
                    // _render_attributes() method to append a special class to the control when rendering it
                    // so that we can also control user input from javascript
                    case 'alphabet':
                    case 'digits':
                    case 'alphanumeric':
                    case 'number':
                    case 'float':

                        $this->set_attributes(array('onkeypress' => 'javascript:return $(\'#' . $this->form_properties['name'] . '\').data(\'Zebra_Form\').filter_input(\'' . $rule_name . '\', event' . ($rule_properties[0] != '' ? ', \'' . addcslashes($rule_properties[0], '\'') . '\'' : '') . ');'));

                        // for controls having these rules,
                        if (in_array($rule_name, array('digits', 'number', 'float')))

                            // change the control's type to "number"
                            $this->set_attributes(array('type' => 'number'));

                        break;

                    // if the rule is about the length of the input
                    case 'length':

                        // if there is a maximum of allowed characters
                        if ($rule_properties[1] > 0) {

                            // set the maxlength attribute of the control
                            $this->set_attributes(array('maxlength' => $rule_properties[1]));

                            // if there is a 5th argument to the rule, the argument is boolean true
                            if (isset($rule_properties[4]) && $rule_properties[4] === true) {

                                // add an extra class so that the JavaScript library will know to show the character counter
                                $this->set_attributes(array('class' => 'show-character-counter'), false);

                            }

                        }

                        break;

                    // if the "email" rule is set
                    case 'email':

                        // change the element's type to "email"
                        $this->set_attributes(array('type' => 'email'));

                        break;

                }

            }

    }