=pod

=head1 NAME

Form::Tiny::Manual::Compatibility - backward compatibility notice

=head1 DESCRIPTION

This documentation page is listing all non-backward compatible changes in usage
of Form::Tiny, together with recipes on how to fix them.

=head2 Compatibility policy

Starting from version I<2.00>, any backward incompatible changes will only be
introduced to the module after a 3 month deprecation period. This does not
cover bug fixes and changes to internal methods not meant to be used or
depended on.

Usually, if the given package / method is documented and the documentation does
not state that it is internal, it will not be changed without any notice unless
a bug is detected or the change corrects some non-logical behavior.

If a change was made which breaks this policy you are welcome to open an issue
in the bugtracker.

=head1 CHANGES

=head2 Subform adjustment no longer requires an explicit call to subform's C<fields>

I<Changed in 2.18 - considered mostly backward compatible>

Previous versions of Form::Tiny automatically inserted an adjustment for
subform fields, which caused the correct behavior of including subform's
C<fields> in main form's C<fields>. Overriding the C<adjust> subroutine
required explicitly taking C<fields> from the subform.

This adjustment is no longer injected and correct behavior is achieved
internally by the validator. Any forms which used explicit adjustments of
subform before should now have a redundant but harmless call to C<fields>,
which can be safely removed.

The only scenario in which it breaks backward compatibility is when subform
field adjustment did not call C<fields>. In this case, an explicit call to
subform's C<input> is required to retain old behavior.

=head2 Form::Tiny::Filter has been moved to Form::Tiny::Plugin::Filtered::Filter

I<Changed in 2.17>

Due to new internal structure, Filter has been moved to Plugin directory.

=head2 is_validated and clear_valid methods are deprecated

I<Changed in 2.10>

Forms no longer store their validation state in a dedicated field. These
methods did nothing starting with version 2.09, and got later removed.

=head2 Subroutine call parameters got standarized

I<Changed in 2.04>

Many parts of the system can be customized with code references (anonymous
subroutines). The problem is they were designed in isolation, per feature and
not as a whole.

Because of this, parameters they get passed tended to vary. For example the
C<default> sub used to get passed a single parameter, which is a form instance,
while form validator would not get passed a form instance, making it hard or
impossible to make use of instance data in certain places.

To combat this, all listed places now consistently get passed the form instance
as their first parameter, followed by their former parameters:

	form_field -> adjust
	form_field -> coerce
	form_validator
	form_filter
	field_filter

For example:

	form_field 'field' => (
		# before
		adjust => sub { shift() + 1 },
		# after
		adjust => sub { $_[1] + 1 },
	);

Or with signatures:

	form_field 'field' => (
		# before
		adjust => sub ($value) { $value + 1 },
		# after
		adjust => sub ($self, $value) { $value + 1 },
	);

=head2 Form::Tiny::Error::DoesNotExist was removed

I<Changed in 2.04>

Use Form::Tiny::Error::Required instead.

=head2 Using three-argument field_filter (passing context explicitly)

I<Changed in 2.04>

	# Old form
	field_filter 'field_name', Type, sub { ... };

	# New form - use context instead
	form_field 'field_name';
	field_filter Type, sub { ... };

=head2 Using Form::Tiny::Filter 'field' property

I<Changed in 2.04>

	# Old form
	field_filter Form::Tiny::Filter->new(
		field => 'field_name',
		type => Type,
		code => sub { ... },
	);

	# New form - use context instead
	form_field 'field_name';
	field_filter Form::Tiny::Filter->new(
		type => Type,
		code => sub { ... },
	);

=head2 Input data is no longer deep cloned before validation

I<Changed in 2.01 - considered bugfix>

In previous versions, the validation process started off by deep cloning the
input by calling C<Storable::dclone> on it. It was unnecessary and had the
potential to lead to subtle bugs.

The validation process is cloning most of the input by itself by mangling
fields and then putting them back in the result hashref, much alike the input
one, but completely separate. However, if you specify that a field should be an
object of certain type, that will not get cloned. Same for explicit array and
hash references (not those specified as a path, like C<key1.key2>). Removing
deep cloning fixed that, as those would get cloned anyway.

So now, if you specify your field to contain something that is not a reference,
it will get cloned. If you specify something that is a reference, it will not
get cloned, and changing it will also change that single key in the input hash.
You have all the power to decide.

If you still want to deep clone your input data you can use the C<reformat>
hook for that. See L<Form::Tiny::Manual/"Hooks">.

=head2 Filtered forms no longer trim strings by default

I<Changed in 2.00>

In the past, declaring a form as filtered caused it to trim strings before
validation by default.

This behavior was removed due to difficulty in designing a sane interface that
would allow opting out of it. An exception of inline forms
(L<Form::Tiny::Inline>) was introduced, which still trim by default when
declared to be capable of filtering.

As this behavior is often needed, a keyword was introduced that allows to
enable it in a form:

	use Form::Tiny -filtered;
	form_trim_strings;

=head2 Sub-based form fields are resolved dynamically

I<Changed in 2.00>

In version I<2.00> a field definition which is built by a subroutine is called
a dynamic field, since it cannot be resolved in the form metaclass due to
access to form object as its first argument. Due to changes on where the field
definitions are stored, these subroutines are no longer ran once for each form
object, but rather multiple times, possibly even during a single validation
process.

This behavior is more correct, as class fields which you can access might
change between validations, and old field building would not take it into
account. However, it also means that subroutines that build form fields B<must
not> to contain any form of non-determinism (like random number generation) or
(to less degree) something variable in time (like datetime or access to busy
database entries).

I<Minor change in 2.03>

As of I<2.03>, the field definitions are still resolved dynamically, but will
keep their state until you trigger form reset by changing the input (with
C<set_input> method). This allows for some degree of randomness in forms, but
it will still change after you set different input. If you really want
randomness that will last for the entire lifetime of an object, regular class
attribute accessed in a dynamic field is your best bet:

	has 'random_field' => (
		is => 'ro',
		default => sub { rand },
	);

	form_field sub {
		my $self = shift;

		# access with $self->random_field;
	};

=head2 Dynamic (sub-based) form fields need to return a name

I<Changed in 2.00>

Previously, this syntax was allowed:

	form_field 'my_field' => sub {
		return {
			type => Int,
		};
	};

Due to changes on how form_field handles its arguments and how fields are
resolved, this now only accepts a subroutine reference, which in turn has to
return name explicitly:

	form_field sub {
		return {
			name => 'my_field',
			type => Int,
		};
	};

=head2 Hooks system has been overhauled

I<Changed in 2.00>

Previously, hooks were just a primitive system based on method overriding:

	sub pre_validate
	{
		my ($self, $data) = @_;

		...; # actual hook code
		return $data;
	}

This system was hard to handle and often buggy due to roles not copying methods
over rather than actual method resolution. It was replaced by a new, much more
powerful system:

	form_hook before_validate => sub {
		my ($self, $data) = @_;

		...; # actual hook code
		return $data;
	};

In the process, C<pre> word in hooks names became C<before>, multiple hooks
became possible, and new hooks were added.

=head2 Field names now need double backslash escaping

I<Changed in 2.00>

Previously, backslash C<\> could only be used in field names before the dot
C<.> to avoid its meaning of nesting operator. There was no way to escape a
star C<*> to have it as a literal hash key name rather than meaning an array.

It has been changed so that backslash escapes every special character in field
names. This means that a backslash must be escaped by another backslash to have
a literal backslash:

	form_field '\\.'; # a literal dot
	form_field '\\\\.'; # syntax error - a literal backslash followed by a nesting separator
	form_field '\\\\\\.'; # a literal backslash followed by a literal dot

=head2 Old builder syntax is no longer supported

I<Changed in 2.00>

In the past, it was possible to define a form by defining three methods in the
package: C<build_fields>, C<build_cleaner> and C<build_filters>. This was a
part of the initial implementation and was later scraped when form metaobject
was introduced.

If you happened to use the module during its early days, you must adjust your
code to the new DSL style. It should not require drastic changes, but rather
moving declarations out from class methods to DSL keywords. Refer to
L<Form::Tiny/"Form domain-specific language"> for details.

=head1 FUTURE COMPATIBILITY

=head2 Current deprecations

None at this time.

=head1 SEE ALSO

=over

=item * L<Form::Tiny::Manual>

=back

