Skip to content

Instantly share code, notes, and snippets.

@mvidner
Created February 25, 2011 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mvidner/843862 to your computer and use it in GitHub Desktop.
Save mvidner/843862 to your computer and use it in GitHub Desktop.
How to set/unset a flag in a space separated list?
#! /usr/bin/env perl
use strict;
use warnings;
use Test::Simple tests => 2 * 9;
use List::Util qw(first);
# In a space separated list of flags, set one flag on or off (add or delete it).
# Don't modify the list unnecessarily.
sub set_flag {
my ($flags, $flag, $on_off) = @_;
my @list = split ' ', $flags;
if ($on_off) {
push @list, $flag unless defined(first {$_ eq $flag} @list);
}
else {
@list = grep {$_ ne $flag} @list;
}
return join ' ', @list;
}
# In a space separated list of flags, set one flag on or off (add or delete it).
# It is OK to move an already present flag.
sub set_flag_always_modify {
my ($flags, $flag, $on_off) = @_;
my @list = split ' ', $flags;
@list = grep {$_ ne $flag} @list;
push @list, $flag if $on_off;
return join ' ', @list;
}
my $TEST_FLAG = "SSL";
my @tests = (
# add
[ "", "", "SSL"],
[ "foo", "foo", "foo SSL"],
[ "foo bar", "foo bar", "foo bar SSL"],
# preserve/remove
[ "SSL", "", "SSL"],
[ "foo SSL", "foo", "foo SSL"],
[ "SSL foo", "foo", "SSL foo"],
[ "foo SSL bar", "foo bar", "foo SSL bar"],
# duplication
[ "SSL SSL", "", "SSL SSL"], # "SSL" ?
# substring
[ "foo SSSLL bar", "foo SSSLL bar", "foo SSSLL bar SSL"],
);
foreach my $test_triple (@tests) {
my ($original, $expected_unset, $expected_set) = @$test_triple;
my $actual_unset = set_flag($original, $TEST_FLAG, 0);
ok($actual_unset eq $expected_unset, "unset in '$original'");
my $actual_set = set_flag($original, $TEST_FLAG, 1);
ok($actual_set eq $expected_set, "set in '$original'");
}
@mvidner
Copy link
Author

mvidner commented Feb 25, 2011

In #perl, "mst" suggested:
if ($on_off) { $flags =~ /\b$flag\b/ or $flags .= " ${flag}"; } else { $flags =~ s/\b$flag\b//; }
and if we care about the leftover spaces:
... else { s/^${flag} //, s/ ${flag}// for $flags; }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment