prefs for checkboxes (boolean)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • philippe_44
    Senior Member
    • May 2008
    • 9345

    prefs for checkboxes (boolean)

    First of all we seem to hardly use any checkboxes. And the ones I've
    found don't define a positive default value. Which probably tells us why
    there haven't been any complaints. Because the ~ indeed is a placeholder
    for the undefined value, not a defined but empty value
    (https://yaml.org/type/null.html).

    I guess a little patch is needed.

    --

    Michael
    LMS 8.2 on Odroid-C4 - SqueezeAMP!, 5xRadio, 5xBoom, 2xDuet, 1xTouch, 1xSB3. Sonos PLAY:3, PLAY:5, Marantz NR1603, Foobar2000, ShairPortW, 2xChromecast Audio, Chromecast v1 and v2, Squeezelite on Pi, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5, RivaArena 1 & 3
  • philippe_44
    Senior Member
    • May 2008
    • 9345

    #2
    prefs for checkboxes (boolean)

    Hi - A question on YT plugin reminded me of an issue I had with preferences and I can't remember if that has already been discussed. To set defaults prefs, my plugins do a $prefs->init( { key1 = >value1, ke2 => value2 }); at startup.
    The problem is that when letting LMS handle preferences automatically, an unchecked box is stored in the .prefs file as "~" and at next plugin (LMS) startup, it is considered as non-set so if the default value is "1/on", then user choice is overwritten again and again.
    Do I miss something?
    LMS 8.2 on Odroid-C4 - SqueezeAMP!, 5xRadio, 5xBoom, 2xDuet, 1xTouch, 1xSB3. Sonos PLAY:3, PLAY:5, Marantz NR1603, Foobar2000, ShairPortW, 2xChromecast Audio, Chromecast v1 and v2, Squeezelite on Pi, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5, RivaArena 1 & 3

    Comment

    • mherger
      Babelfish's Best Boy
      • Apr 2005
      • 24643

      #3
      prefs for checkboxes (boolean)

      > The problem is that when letting LMS handle preferences automatically,
      > an unchecked box is stored in the .prefs file as "~" and at next plugin
      > (LMS) startup, it is considered as non-set so if the default value is
      > "1/on", then user choice is overwritten again and again.


      Haven't tested this right now, but that's indeed not what I'd expect to
      happen. IMHO "~" isn't "undefined", but "empty". I know that Perl
      sometimes is a bit vague on these. But the prefs init code should check
      undefined vs. defined only. I'd be surprised if with the gazillion of
      options we have in LMS this would not have cropped up before...

      Could it be a Perl version issue? Are you using a stock LMS package with
      the built-in binaries for YAML etc.?

      --

      Michael
      Michael

      "It doesn't work - what shall I do?" - "Please check your server.log and/or scanner.log file!"
      (LMS: Settings/Information)

      Comment

      • philippe_44
        Senior Member
        • May 2008
        • 9345

        #4
        Originally posted by mherger
        > The problem is that when letting LMS handle preferences automatically,
        > an unchecked box is stored in the .prefs file as "~" and at next plugin
        > (LMS) startup, it is considered as non-set so if the default value is
        > "1/on", then user choice is overwritten again and again.


        Haven't tested this right now, but that's indeed not what I'd expect to
        happen. IMHO "~" isn't "undefined", but "empty". I know that Perl
        sometimes is a bit vague on these. But the prefs init code should check
        undefined vs. defined only. I'd be surprised if with the gazillion of
        options we have in LMS this would not have cropped up before...

        Could it be a Perl version issue? Are you using a stock LMS package with
        the built-in binaries for YAML etc.?

        --

        Michael
        That was with my main LMS version:

        Logitech Media Server Version: 7.9.2 - 1564587295 @ Wed Jul 31 17:50:00 CEST 2019
        Hostname: multimedia
        Server IP Address: 192.168.2.144
        Server HTTP Port Number: 9000
        Operating system: Debian - EN - utf8
        Platform Architecture: armv7l-linux
        Perl Version: 5.24.1 - arm-linux-gnueabihf-thread-multi-64int
        Audio::Scan: 1.02
        IO::Socket::SSL: 2.044
        Database Version: DBD::SQLite 1.58 (sqlite 3.22.0)
        Total Players Recognized: 39

        I agree and this surprised me too, but I tried with a few of my plugins and look at the code of others and checked what is written in .prefs files
        I also found an old note I put for myself in one of my plugins where I decided to not set an init value to 1 for a checkbox prefs for this exact reason.
        The prefs code checks for "exist" or "defined" (in prefs/Base.pm)
        Code:
        if (!exists $class->{'prefs'}->{ $pref } || !defined $class->{'prefs'}->{ $pref }) {
        But I don't know yet how this hash is loaded from the .prefs file
        LMS 8.2 on Odroid-C4 - SqueezeAMP!, 5xRadio, 5xBoom, 2xDuet, 1xTouch, 1xSB3. Sonos PLAY:3, PLAY:5, Marantz NR1603, Foobar2000, ShairPortW, 2xChromecast Audio, Chromecast v1 and v2, Squeezelite on Pi, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5, RivaArena 1 & 3

        Comment

        • mherger
          Babelfish's Best Boy
          • Apr 2005
          • 24643

          #5
          Not sure about the patch any more: as we cannot know whether an empty value had been reset by a checkbox or something else, we can not rely on that value. This is really an issue only with values which a.) default to a non-empty value, and b.) use a checkbox as the UI element.

          I see two workarounds:
          • Don't use checkboxes, but other input methods. We often use a dropdown with the two choice descriptions as the labels.
          • Add a change handler which would override the undefined value with a defined, but falsy value:


          Code:
          	$prefs->setChange(sub {
          		my ($prefname, $value, $client) = @_;
          		if (!defined $value) {
          			$prefs->set($prefname, 0);
          		}
          	}, 'pref1', 'pref2', 'pref3', ...);
          As the init code only is being run during startup, this should be a safe method. Just make sure you really do check for undefined, or you might end up in an endless loop... you can add as many pref names to the setChange call as you need.
          Last edited by mherger; 2019-08-26, 16:48.
          Michael

          "It doesn't work - what shall I do?" - "Please check your server.log and/or scanner.log file!"
          (LMS: Settings/Information)

          Comment

          • mrw
            Senior Member
            • May 2010
            • 1083

            #6
            Originally posted by mherger
            • Add a change handler which would override the undefined value with a defined, but falsy value:
            I think I ended up doing that, once. For what it's worth, here is a comment I wrote at some point:

            # Although logically 'undef' is equivalent to 0 in a boolean test, in SBS 7.8
            # the '$prefs->init' method considers 'undef' to be unitialized, so may give
            # unexpected behaviour.

            So perhaps there was a behaviour change in SBS 7.8, as I seem to have thought at the time.

            Comment

            • philippe_44
              Senior Member
              • May 2008
              • 9345

              #7
              Originally posted by mherger
              Not sure about the patch any more: as we cannot know whether an empty value had been reset by a checkbox or something else, we can not rely on that value. This is really an issue only with values which a.) default to a non-empty value, and b.) use a checkbox as the UI element.

              Code:
              	$prefs->setChange(sub {
              		my ($prefname, $value, $client) = @_;
              		if (!defined $value) {
              			$prefs->set($prefname, 0);
              		}
              	}, 'pref1', 'pref2', 'pref3', ...);
              As the init code only is being run during startup, this should be a safe method. Just make sure you really do check for undefined, or you might end up in an endless loop... you can add as many pref names to the setChange call as you need.
              I'll do that - Thank you as usual
              LMS 8.2 on Odroid-C4 - SqueezeAMP!, 5xRadio, 5xBoom, 2xDuet, 1xTouch, 1xSB3. Sonos PLAY:3, PLAY:5, Marantz NR1603, Foobar2000, ShairPortW, 2xChromecast Audio, Chromecast v1 and v2, Squeezelite on Pi, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5, RivaArena 1 & 3

              Comment

              Working...