FHEM Coding Conventions

Begonnen von igami, 23 Januar 2018, 05:17:52

Vorheriges Thema - Nächstes Thema

igami

Wie ist eure Meinung zum Thema Coding Conventions?
Ich bin, wie manch anderer auch, kein gelernter Informatiker, sondern eigne mir mein Wissen durch lesen und nachmachen an.
Damit sich bei der Vielfalt von Modulen auch andere Entwickler in fremdem Code zurecht finden sollte die Struktur durch ein paar Vorgaben definiert werden.

Ich fange mal damit an wie ich meine Module aufbaue und würde mich freuen, wenn wir hier ein paar sinnvolle Richtlinien Festlegen könnten:

1. Id

# Id ##########################################################################
# $Id: 74_Nmap.pm 14107 2017-04-26 03:51:05Z igami $


2. Copyright

# copyright ###################################################################
#
# 74_Nmap.pm
#
# Copyright by igami
#
# This file is part of FHEM.
#
# FHEM is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# FHEM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with FHEM.  If not, see <http://www.gnu.org/licenses/>.


wie man an den beiden Punkten sieht nutze ich eine 79 Zeichen Lange Doppelkreuz Zeile in der immer der Inhalt der nachfolgenden Zeilen beschrieben ist. Davon gibt es dann noch weitere in folgender Reihenfolge:

# packages ####################################################################
# variables ###################################################################
# forward declarations ########################################################
# initialize ##################################################################
# regular Fn ##################################################################
# HttpUtils Fn ################################################################
# blocking Fn #################################################################
# module Fn ###################################################################
# commandref ##################################################################


Die Sektion forward declarations dient nebenbei auch wieder als Übersicht. Hier werden alle subs in Reihenfolge aufgeführt, wobei einzelne Sektionen durch eine Leerzeile getrennt sind.
Beispiel 76_msgDialog

# forward declarations ########################################################
sub msgDialog_Initialize($);

sub msgDialog_Define($$);
sub msgDialog_Set($@);
sub msgDialog_Get($@);
sub msgDialog_Notify($$);

sub msgDialog_progress($$$;$);
sub msgDialog_reset($);
sub msgDialog_evalSpecials($$);
sub msgDialog_updateAllowed;


Die Initialize sub ist bei mir folgendermaßen aufgebaut:

sub X_Initialize($) {
  my ($hash) = @_;
  my $TYPE = "X";
 
  $hash->{DefFn}      = "$TYPE\_Define";
  $hash->{UndefFn}    = "$TYPE\_Undef";
  $hash->{DeleteFn}   = "$TYPE\_Delete";
  $hash->{SetFn}      = "$TYPE\_Set";
  $hash->{GetFn}      = "$TYPE\_Get";
  $hash->{AttrFn}     = "$TYPE\_Attr";
  $hash->{ReadFn}     = "$TYPE\_Read";
  $hash->{ReadyFn}    = "$TYPE\_Ready";
  $hash->{NotifyFn}   = "$TYPE\_Notify";
  $hash->{RenameFn}   = "$TYPE\_Rename";
  $hash->{ShutdownFn} = "$TYPE\_Shutdown";

  $hash->{AttrList} =
    "disable:0,1 ".
    "disabledForIntervals ".
    $readingFnAttributes
  ;
}

Hier kommen dann auch schon die ersten Unklarheiten:
1. Wie soll die Definition der sub "Zeile" aussehen? Zeilenumbruch nach sub und vor der { oder alles in einer Zeile? Ich nutze letzeres, da es dann mit dem Code Folding in meinem Editor besser funktioniert.
2. Die Funktionen mit Leerzeichen so formatieren, dass alle = untereinander stehen?
3. Bei mehrzeilig-verknüpften Texten den . an den Anfang oder an das Ende der Zeile?
4. Einrücken durch Tabulator oder durch Leerzeichen?

Das soll an dieser Stelle genügen um eine Diskussion zu ermöglichen. Bei Bedarf kann ich meine Conventions gerne noch fortführen.

Grüße
Michael
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

rudolfkoenig

$Id:$ (mit entsprechenden svn propset) ist wichtig, sonst funktioniert version nicht.

Alles Andere sollte nicht vorgeschrieben werden, weil die Entwickler unterschiedliche Tools verwenden und unterschiedliche Beduerfnisse haben. Als Beispiel: ich mag kein Folding, und suche nach der Definition einer Funktion, indem ich Funktionsname am Anfang der Zeile suche. Ja, ich weiss, dass man das Problem mit diversen Tools anders loesen kann, und da waeren wir wieder bei den Beduerfnissen.

Das heisst nicht, dass ich gegen Vorschlaege fuer Unentschlossene bin, ich will diese aber nicht erzwingen.

mahowi

Ich lasse nach dem Editieren immer perltidy drüber laufen. Mit dem Schalter "-w" aufgerufen, werden auch gleich noch Fehler angezeigt.
CUBe (MAX): HT, FK | CUBe (SlowRF): ESA2000WZ
JeeLink: LaCrosse | nanoCUL433: Smartwares SHS-51001-EU, EM1000GZ
ZME_UZB1: GreenWave PowerNode, Popp Thermostat | SIGNALDuino: HE877, X10 MS14A, Revolt NC-5462,  IT Steckdosen + PIR
tado° | Milight | HUE, Lightify | SmarterCoffee

Markus Bloch

Hallo zusammen,

Ob man nun "sub", den Funktionsnamen und die öffnende Klammer auf einer Zeile schreibt sehe ich weniger als notwendige Guideline, da es dem Nutzer nichts bringt. Viel wichtiger mMn sind hier folgende Punkte:

- Verwendung von readings*update()-Funktionen (ermöglicht dem User event-on-*-Attribute, do_not_notify, etc.)
- keine blockierenden HTTP-Request/IO-Operationen die zu einem erliegen von FHEM führen (gibt diverse Ansätze wie man sowas non-blocking lösen kann)
- bei Event-Verarbeitung (NotifyFn) setzen von $hash->{NOTIFYDEV} zur Entlastung der Event-Maschinierie vor unnötigen Aufrufen der NotifyFn (Performance-gewinn insbesondere bei großen Installationen)
- klares Benamungsschema für Readings/Attribute (lowerCamelCaps)
- Nutzung von DevIo für TCP-Verbindungen (wird gerne im Modul selber mit IO::Socket::INET geöffnet usw.)
- Nutzung von HttpUtils für HTTP-Verbindungen (wird gerne im Modul selber mit LWP::UserAgent blockierend gelöst, etc.)
- ...

Deine Vorschläge sind reine optische Vorschläge wie der Code aussehen/formatiert sein sollte. Ich persönlich halte die inhaltliche Ausgestaltung für wichtiger.

Viele Grüße

Markus




Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Zitat von: Markus Bloch am 23 Januar 2018, 10:02:56
Ob man nun "sub", den Funktionsnamen und die öffnende Klammer auf einer Zeile schreibt sehe ich weniger als notwendige Guideline, da es dem Nutzer nichts bringt.

Das würde ich so pauschal nicht unterschreiben. Mein Editor bietet eine "collapse" Funktion, die sehr wohl danach unterscheidet, ob die öffnende Klammer in der gleichen Zeile wie das "sub" steht oder nicht.

Grundsätzlich sehe ich aber keinerlei Handlungsbedarf, in dieser Richtung wieder einmal etwas kaputtregulieren zu müssen.


Und könnte bitte mal jemand den Thread-Titel berichtigen?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

fhainz

Zitat von: betateilchen am 23 Januar 2018, 12:07:30
Grundsätzlich sehe ich aber keinerlei Handlungsbedarf, in dieser Richtung wieder einmal etwas kaputtregulieren zu müssen.
Ob jetzt die öffnende Klammer in der gleichen Zeile steht oder nicht sehe ich auch sehr unkritisch und das soll jeder machen wie er das gerne haben möchte.
Aber nehmen wir mal die Attribute her. Manche fangen mit Großbuchstaben an, manche mit Kleinbuchstaben. Teilweise wird camelCase verwendet, teils _ . Das selbe gilt für Readings, Device-TYPE's, etc. In der Attribut Drop-Down Liste war ich schon öfters am suchen und hab mich geärgert das a != A ist.
Ich finde nicht das soetwas unter die Kategorie kaputtregulieren fällt und man darüber schon reden sollte.

igami

Ich dachte auch eher an Richtlinien als an Regeln ;)
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

betateilchen

@fhainz das von Dir angesprochene Thema bezüglich attribute und reading wird bereits an anderer Stelle diskutiert. Übrigens nicht zum ersten Mal in den Jahren, die ich jetzt in FHEM unterwegs bin.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!