Why Is Guard Stopping

Why is guard stopping?

What your seeing is the Guard interactor, which makes use of Pry. Normally the prompt looks a bit different, so I assume you've a ~/.pryrc file with some configuration. With Guard 1.5.3, released yesterday, Guard ignores ~/.pryrc and only evaluates ~/.guardrc for the Pry configuration, so the normal Pry configuration is separated from the Guard Pry interactor.

When you're seeing this prompt, it means that Guard is waiting and has nothing to do. You can now start working and Guard automatically starts testing your app with minitest according to your file modifications and watcher configuration, or you can manually trigger an action.

You can get a list of the available actions with help guard. Some commands are generated depending on your Guard plugins and groups within your Guardfile. Here's an example of one of my projects:

$ bundle exec guard 
09:58:14 - INFO - Guard uses GNTP to send notifications.
09:58:14 - INFO - Guard is now watching at '/Users/michi/Repositories/extranett'
09:58:15 - INFO - Guard::Jasmine starts Unicorn test server on port 8888 in development environment.
09:58:17 - INFO - Waiting for Jasmine test runner at http://dnndev.me:8888/jasmine
09:58:23 - INFO - Run all Jasmine suites
09:58:23 - INFO - Run Jasmine suite at http://dnndev.me:8888/jasmine
09:58:41 - INFO - Finished in 8.853 seconds
09:58:41 - INFO - 896 specs, 0 failures
09:58:41 - INFO - Done.
09:58:41 - INFO - Guard::RSpec is running
09:58:41 - INFO - LiveReload 1.6 is waiting for a browser to connect.
[1] guard(main)> help guard
Guard
all Run all plugins.
backend Run all backend
change Trigger a file change.
coffeescript Run all coffeescript
frontend Run all frontend
jasmine Run all jasmine
livereload Run all livereload
notification Toggles the notifications.
pause Toggles the file listener.
reload Reload all plugins.
rspec Run all rspec
show Show all Guard plugins.
[2] guard(main)> exit
09:59:39 - INFO - Guard::Jasmine stops server.
09:59:39 - INFO - Bye bye...

Navigation Guard Stopping Me Going to Page

VueEvent.$on('disregard_changes', ...), but your component has this.$emit('disregard_changes', ...), which does not emit the event on the event bus in VueEvent.

Solution: Change this.$emit to VueEvent.$emit

Why is guard based on Alternative?

TL;DR: Historical reasons. It was envisioned like this in MonadPlus, which got its Applicative variant Alternative later, and no one has proposed to split Alternative into AZero and AChoice or similar.


Alternative is a relatively new idea, just like Applicative. Back when guard was first envisioned, it was based on MonadPlus, a Monad that should support choice and failure, just like Alternative. Its original type was thus

guard :: MonadPlus m => Bool -> m ()

That was specified in the Haskell 98 report, where MonadPlus was already noted. Haskell 1.0 didn't use monads at all, by the way. When Applicative finally got a superclass of Monad, Alternative got a superclass of MonadPlus, and mzero = empty and mplus = (<|>).

Well, now we know why guard uses Alternative. Because it was based on MonadPlus beforehand. So why is MonadPlus defined like this?

One would have to write a mail to SPJ or someone else from the committee to get their rationale from 1998, because just one year later, Erik Meijer and Graham Hutton wrote their "Monadic Parsing in Haskell" paper. If you have a look at the paper, you'll notice that their MonadPlus just works like you intend:

class Monad m => MonadZero m where
zero :: m a

class MonadZero m => MonadPlus m where
(++) :: m a -> m a -> m a

So it's certainly possible to handle this "stoppable" the way you've described it. However, there is simply no base class that currently defines empty without Alternative. There could be one, but it wasn't proposed yet.

Note that this is a recurring theme with Haskell classes. Monoid contains mappend and mempty. After its conception, someone noticed that there are certain types where mappend makes sense, but not mempty. For example

newtype Min a = Min a

combine :: Ord a => Min a -> Min a -> Min a
combine (Min x) (Min y) = Min (min x y)

Here, mappend = combine is clearly associative, whereas an empty Min isn't possible if we just use Ord, we would have to use Bounded. That's why there is now Semigroup, which isn't a base class of Monoid yet, but gives us that associative operation.

To come back to your original question: guard uses Alternative, because Alternative provides empty, and empty "stops" the evaluation in certain Alternative's. There's no other class that contains that, yet.

But with a proposal, there might be at some point, although I'm not sure what's the community's opinion on splitting Alternative is.

By the way, languages like PureScript split Alternative, although they split it the other way round…

For more information about Alternative and why I used Monoid as another example, see Confused by the meaning of the 'Alternative' type class and its relationship to other type classes.

How do I configure Guard to skip the Pry prompt and just run my changed test?

Taken from the Guard Wiki:


If you are on Mac OS X and have problems with either Guard not reacting to file changes or Pry behaving strangely, then you probably suffer under a Ruby build that uses `libedit` instead of `readline`.

So I highly recommend to follow the instructions in the Guard wiki and recompile your Ruby version with proper Readline support.

As alternative you could also use the older Guard version 1.4.0 that comes with the simple gets based interactor, see the old README for supported features of that versions. To get the simple interactor, add


interactor :simple

to your Gemfile.

Guard let is executing, but the code after it still works?

There are some MKAnnotations that are not the class of JumpSpotAnnotation when func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? works. It must be from MKMapView so dont worry about it. Your guard let works well.

Angular Route Guard CanActivate stops routing

Change subscribe to map that returns Observable<boolean>

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
var _this = this;
return this.appService.getUserViewData().map(user => {
if (user.LoggedInCompany != null) {
return true;
} else {
_this.router.navigate(['/login']);
return false;
}
});
}

Angular CanDeactivate Guard Not Working Properly With MatDialog

It is exactly the way you describe it.

Your route guard expects immediately true or false. It isn't capable of dealing with observables.

So my suggestion is to do the following.

First

Have your check, but directy return false, when the component is dirty so that the route guard prevents a rerouting. Build up a service, that stores the new route and contains a field named, for instance, reroutingAllowed. This is initially set to false.

canDeactivate(component: DirtyComponent): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return component?.isDirty();
}

confirmRouteChange() {
// here we already take the new field into account
if (this.isDirty && !reroutingAllowed) {
let dialogRef = this.matDialog.open(AlertModalComponent, {
data: {
msg: 'Your changes have not been saved. If you leave this page, your changes will be lost.',
title: 'Changes have not been saved',
class: 'save-changes'
}
});

// directly return false
return false;
} else {
return true;
}
}

Second

Momorize parallely the new route target the user wanted to go to in your service in order to have access to it when the user met its decission in the modal dialog.

Third

Wait for the user to answer the dialog. If he wants to leave the current page set the variable reroutingAllowed to true and trigger the Angular router to call the new route target again.

This time the guard will let the user pass, event though the form is still dirty.

You just have to think about how to set up the mentioned service an how to get and memorize the new route target.



Related Topics



Leave a reply



Submit