Announcement

Collapse
No announcement yet.

Warning about Early Binding

Collapse
This is a sticky topic.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Warning about Early Binding

    Developers of Plug-Ins:

    If you are not familiar with the terms Early Binding and Late Binding, let me try to give a layman's description: Early binding involves the compiler having the prototypes (descriptions) of all of the procedures you are using in HomeSeer sort of "hard coded". It looks at the reference to HomeSeer's scheduler and saves the prototypes as well as the version, and that avoids the alternative (late binding) which can be slower. Late binding is where you are referencing an object (in this case the HomeSeer Scheduler) as an object, and when your code makes a call into HomeSeer, it finds the prototype of the procedure you are calling for purposes of passing parameters at the time the call is made.

    We have always warned developers not to use early binding, but have not officially documented it in the SDK or posted it here, so that is why I am posting this now.

    If you use early binding because in your development environment it shows you the prototype for the procedure you are calling (and all of the properties you are referencing) then that is fine, but you must convert it to late binding before you compile it for distribution to users.

    If you do not do this and you leave your plug-in using early binding, then what happens is that when we make a change to HomeSeer, your plug-in instantly breaks. Case in point: I just made a change that adds a 3rd optional parameter to WriteLog (hs.WriteLog) which is a very popular procedure... A plug-in that I had active on my development system because I was testing its installer suddenly burped, because even though the new 3rd parameter was optional, the prototype had changed so it did not find the version of HomeSeer's scheduler that it expected.

    So please remember to use late binding in your final product being shipped to users!
    Regards,

    Rick Tinker (a.k.a. "Tink")

    #2
    Rick, that's bad programming on the HomeSeer/your side, not the plug-in developer. I've been a commercial programmer for decades; no real system changes the prototypes that way, regardless of late binding. Instead you overload or extend the API.

    Examples:

    Changing
    DoFoo(int X, int Y, time_t When)
    to
    DoFoo(int X, int Y, time_t When, string Where = NULL)

    is an incompetent, immature change.

    To do this correctly, you could either have originally implemented:
    DoFoo(int X, int Y, time_t When, ...)
    best with C, not real easy in C#/VB, but it does allow infinite later expansion,

    or

    DoFooEx(int X, int Y, time_t When, string Where)
    Note that the name has changed a bit and now Where is not optional.

    or support both methods, if running in a purely object-oriented world...
    DoFoo(int X, int Y, time_t When)
    DoFoo(int X, int Y, time_t When, string Where)

    But under no circumstances should you REMOVE previous APIs.

    If y'all need some references on good/competent programming practices, I'm sure a lot of us old dawgs can point you at them.

    Comment


      #3
      I absolutely agree with TechnoCat. Breaking an existing API with a new release is totally unacceptable and VERY poor programming practice.

      tenholde
      tenholde

      Comment


        #4
        Yesterday's announcement of 2.3.0.33 HS2 release notes suggest they listened and added a new function to extend the writeLog function.
        HS3 Pro Edition 3.0.0.435 (Windows 10 vmware)
        BLOccupied:,UltraNetCam3:,weatherXML:,RFXCOM:,Current Cost 3P:,UltraGCIR3:
        DMMQTT:,Kodi:,Z-Wave:,BLRadar:,EasyTrigger:,MySensors:,BLBackup:

        Comment


          #5
          Guys, HST did it again!

          They changed the api to hs.runex. Why can't they use overloads to add functionality without breaking existing methods.

          would the following definition work so we could continue to use early binding?

          Code:
          Public Class Class1
          
              Public Overloads Sub method1(ByVal x As Integer)
          
                  method1(x, False) ' false would be the default value
          
              End Sub
          
              Public Overloads Sub method1(ByVal x As Integer, ByVal y As Boolean)
              End Sub
          
          End Class
          Mark

          HS3 Pro 4.2.19.5
          Hardware: Insteon Serial PLM | AD2USB for Vista Alarm | HAI Omnistat2 | 1-Wire HA7E | RFXrec433 | Dahua Cameras | LiftMaster Internet Gateway | Tuya Smart Plugs
          Plugins: Insteon (mine) | Vista Alarm (mine) | Omnistat 3 | Ultra1Wire3 | RFXCOM | HS MyQ | BLRadar | BLDenon | Tuya | Jon00 Charting | Jon00 Links
          Platform: Windows Server 2022 Standard, i5-12600K/3.7GHz/10 core, 16GB RAM, 500GB SSD

          Comment


            #6
            Personal opinion: I don't think Rick saw any of the replies to this back in response to his initial post, and I'm guessing he won't see these either. I'd suggest someone needs to send he and/or Rich an email on this topic to either cause it to be explained to everyone's satisfaction or correct the practice of changing a method's signature vs. overloading it. Although I agree with what others have said here, it may well be there is some reason HST has decided they must replace vs. overload. Since Rick has never replied I'd give him the benefit of the doubt that he never even saw the first response over a year ago.

            Steve

            Comment


              #7
              Originally posted by stevea View Post
              Personal opinion: I don't think Rick saw any of the replies to this back in response to his initial post, and I'm guessing he won't see these either. I'd suggest someone needs to send he and/or Rich an email on this topic to either cause it to be explained to everyone's satisfaction or correct the practice of changing a method's signature vs. overloading it. Although I agree with what others have said here, it may well be there is some reason HST has decided they must replace vs. overload. Since Rick has never replied I'd give him the benefit of the doubt that he never even saw the first response over a year ago.

              Steve
              Thanks for the suggestion. I'll send and email to Rick and Rich an email and see if they will comment on this thread.

              FWIW, i did send this "overload" suggestion directly to Rich after he confirmed that they did change the runex method. But i did not hear back.

              Before I push too much, is the overloading suggestion possible? Would this actually allow us to continue to use early binding?

              I could see the other side were a developer uses a newer method that is not provided in an older hs build which could cause problems as well. but i guess the developer could control this via version checking.

              Mark
              Mark

              HS3 Pro 4.2.19.5
              Hardware: Insteon Serial PLM | AD2USB for Vista Alarm | HAI Omnistat2 | 1-Wire HA7E | RFXrec433 | Dahua Cameras | LiftMaster Internet Gateway | Tuya Smart Plugs
              Plugins: Insteon (mine) | Vista Alarm (mine) | Omnistat 3 | Ultra1Wire3 | RFXCOM | HS MyQ | BLRadar | BLDenon | Tuya | Jon00 Charting | Jon00 Links
              Platform: Windows Server 2022 Standard, i5-12600K/3.7GHz/10 core, 16GB RAM, 500GB SSD

              Comment


                #8
                Mark,

                I'm a script guy, so this binding stuff is for you plug-in-junkies...

                In my BetaBrite script I have a couple of classes where I have 3 overloaded methods by the same name, all different only in the number and type of parameters, and until I saw your post I didn't even know there was an "overloads" keyword in VB.NET. In mine, they are just declared as public, and it all gets figured out based on the signature of the method compared to how it is called. I guess that sounds lots like early binding binding to me.

                Steve

                Comment


                  #9
                  Originally posted by Rick Tinker View Post
                  So please remember to use late binding in your final product being shipped to users!
                  It's just a case of switching:
                  Code:
                  Public hs As Scheduler.hsapplication
                  to
                  Code:
                  Public hs As Object
                  right?


                  I fail to see why HST actually would prefer to use late binding as it consumes more resources. Wouldn't be a good idea to do whatever you can to avoid wasting time and resources?
                  HSPro 3.0.0.458, Z-NET with Z-wave plugin 3.0.1.190, RFXCOM + 2x RFXtrx433E, HSTouch, Squeezebox plugin, iTach IP/WF2IR & GC-100-6 with UltraGCIR, BLDenon, NetcamStudio, Jon00s Webpage builder, Harmony Hub plugin, SCSIP (with FreePBX), Arduino plugin, IFTTT, Pushalot plugin, Device History plugin.
                  Running on Windows 10 (64) virtualized
                  on ESXi (Fujitsu Primergy TX150 S8).
                  WinSeer (for Win10) - TextSeer - FitbitSeer - HSPI_MoskusSample

                  Are you Norwegian (or Scandinavian) and getting started with HomeSeer? Read the "HomeSeer School"!

                  Comment


                    #10
                    I am curious how many HS plugins got affected by said API changes?

                    Obviously many folks from both sides of the fence didn't read the initial post and made assumptions or got surprised.
                    - Pete

                    Auto mator
                    Homeseer 3 Pro - 3.0.0.548 (Linux) - Ubuntu 18.04/W7e 64 bit Intel Haswell CPU 16Gb
                    Homeseer Zee2 (Lite) - 3.0.0.548 (Linux) - Ubuntu 18.04/W7e - CherryTrail x5-Z8350 BeeLink 4Gb BT3 Pro
                    HS4 Lite - Ubuntu 22.04 / Lenovo Tiny M900 / 32Gb Ram

                    HS4 Pro - V4.1.18.1 - Ubuntu 22.04 / Lenova Tiny M900 / 32Gb Ram
                    HSTouch on Intel tabletop tablets (Jogglers) - Asus AIO - Windows 11

                    X10, UPB, Zigbee, ZWave and Wifi MQTT automation-Tasmota-Espurna. OmniPro 2, Russound zoned audio, Alexa, Cheaper RFID, W800 and Home Assistant

                    Comment


                      #11
                      As I explained to Mark, we cannot use overloads unless the prototype for the procedure is substantially different - you cannot for example overload a procedure if the only difference is in the optional parameters, which is what the case was here.

                      For this reason and others, we always encourage the use of late binding so that plug-ins are not tied to specific versions of HomeSeer. I understand that Mark's development environment does not allow late binding, but hopefully he can understand that it is very difficult for us to not make any changes to the interface.

                      This is why we put out betas and expect application providers to test against these beta versions, and that is what happened in this case - it was caught in beta, providing time for the plug-in to be updated.

                      I have made a change to accommodate Mark's plug-in - I put Run and RunEx back the way they were, and created new procedures RunScript and RunScriptEx that have the optional parameters. The only issue now is that a few years from now, we will wonder why we have Run and RunEx, and if there are plug-ins bound to those procedures - we have procedures in HomeSeer that were abandoned years go for this reason!
                      Regards,

                      Rick Tinker (a.k.a. "Tink")

                      Comment


                        #12
                        Originally posted by Rick Tinker View Post
                        As I explained to Mark, we cannot use overloads unless the prototype for the procedure is substantially different - you cannot for example overload a procedure if the only difference is in the optional parameters, which is what the case was here.
                        Rick,

                        Maybe there is something different in this particular case, but one of the main reasons to overload is when you have optional parameters. You can have overloaded versions of the same method, each with a different number of parameters. So instead of changing the single signature of a method to add some optional parameters, you have one with no optional parameters, and another with the extra parameters. That's overloading.

                        Am I missing something?

                        Steve

                        Comment


                          #13
                          Steve,

                          It won't work if the only difference is the optional parameter.

                          Run used to have only the script name parameter.
                          Run was modified to have two optional parameters (wait and single instance) and so overloading was not allowed. The two new parameters had to be optional or we would have broken EVERYBODY, not just plug-ins that use early binding.

                          RunEx used to have 3 required parameters and one optional parameter.
                          RunEx was modified to have two optional parameters - again, disallowed for overloading.


                          So Run and RunEx are back to the way they were, and we now have RunScript and RunScriptEx
                          Regards,

                          Rick Tinker (a.k.a. "Tink")

                          Comment


                            #14
                            ...
                            HSPro 3.0.0.458, Z-NET with Z-wave plugin 3.0.1.190, RFXCOM + 2x RFXtrx433E, HSTouch, Squeezebox plugin, iTach IP/WF2IR & GC-100-6 with UltraGCIR, BLDenon, NetcamStudio, Jon00s Webpage builder, Harmony Hub plugin, SCSIP (with FreePBX), Arduino plugin, IFTTT, Pushalot plugin, Device History plugin.
                            Running on Windows 10 (64) virtualized
                            on ESXi (Fujitsu Primergy TX150 S8).
                            WinSeer (for Win10) - TextSeer - FitbitSeer - HSPI_MoskusSample

                            Are you Norwegian (or Scandinavian) and getting started with HomeSeer? Read the "HomeSeer School"!

                            Comment


                              #15
                              I am now truly confused by the response to this issue.

                              Method overloading can be used for both differing argument type and count.

                              It would seem that it would be reasonable to define an overload for each combination of supplied parameters, instead of defining them as optional. Each overload definition with fewer than the max parameters would define the missing parameters using defaulted value and all call the same core method.

                              The problem with changing (enhancing) interfaces is easily handled via overloads.

                              tenholde
                              tenholde

                              Comment

                              Working...
                              X