Make sure a setter is public before invoking it

`method_exists()` doesn't say whether the method is callable in the current scope, so if a setter is `protected`/`private` it'll be called and a fatal error is raised.

This PR changes it to match the property test by making sure it's accessible first.

(The other option is to make it `method_exists($instance, 'set'.$key) && is_callable(array($instance, 'set'.$key))`, but this method allows Alice to pick up the typehinting - though you could do some reflection in the property setting block.)