Pregunta

En caso de que no saben Proyecto Lombok ayuda con algunas de las molestias de Java con cosas como generar captadores y definidores con anotaciones e incluso JavaBean sencilla como la generación con @Data . Realmente me podría ayudar, especialmente en 50 diferentes objetos de eventos donde se tiene hasta 7 campos diferentes que se tienen que construir y ocultos con captadores. Trasladase casi mil líneas de código con esto.

Sin embargo, me preocupa que, a la larga, será una decisión lamentable. Flamewars harán erupción en el canal ##Java Freenode cuando lo menciono, proporcionando fragmentos de código confundirá posibles ayudantes, las personas se quejan de falta JavaDoc , y futuras commiters sólo podría eliminar todo de todos modos. Yo realmente disfrutar de lo positivo, pero estoy preocupado por la negativa.

Así que: ¿Es seguro utilizar Lombok en cualquier proyecto, grande o pequeño? Son el valor de los efectos positivos de los negativos?

¿Fue útil?

Solución

Parece que ya ha decidido que el Proyecto Lombok le ofrece ventajas técnicas significativas para su nuevo proyecto propuesto. (Para que quede claro desde el principio, no tengo puntos de vista particulares sobre Proyecto de Lombok, de un modo u otro.)

Antes de utilizar Proyecto Lombok (o cualquier otra tecnología que cambia el juego) en algún proyecto (de código abierto o de otra forma), es necesario asegurarse de que las partes interesadas del proyecto de acuerdo con esto. Esto incluye los desarrolladores, y cualquier usuario importantes (por ejemplo, formal o informal patrocinadores).

Usted menciona estos posibles problemas:

  

flamewars entrará en erupción en el canal ## de Java Freenode cuando lo menciono,

Fácil. Ignorar / no participan en las flamewars, o simplemente dejar de mencionar Lombok.

  

proporcionar fragmentos de código confundirá posibles ayudantes,

Si la estrategia del proyecto es el uso de Lombok, a continuación, tendrá que acostumbrarse a él los posibles ayudantes.

  

personas se quejan de falta JavaDoc,

Ese es su problema. Nadie en su sano juicio trata de aplicar rígidamente las reglas del código fuente y / o documentación de su organización de software de código abierto de terceros. El equipo del proyecto debe estar libre a las normas de código / fuente de documentación de proyecto conjunto que sean apropiados a la tecnología utilizada.

( FOLLOWUP -. Los desarrolladores de Lombok reconocer que no generando comentarios Javadoc para los métodos get y set sintetizados es un problema si esto es un problema importante para su proyecto (s), a continuación, una alternativa es crear y enviar un parche a Lombok dirección de este.)

  

y futuras commiters sólo podría eliminar todo de todos modos.

Ese no es el! Si la estrategia del proyecto acordado es el uso de Lombok, a continuación, commiters que gratuitamente de-Lombok el código debe ser castigado, y si es necesario se han retirado sus cometer derechos.

Por supuesto, esto supone que usted tiene aceptación por parte de los actores ... incluyendo los desarrolladores. Y se supone que usted está preparado para argumentar su causa, y de manera adecuada de manejar las voces discrepantes inevitables.

Otros consejos

Sólo comenzó a usar Lombok hoy. Hasta ahora me gusta, pero una desventaja que no vi fue mencionado refactorización apoyo.

Si usted tiene una clase anotada con @Data, generará los captadores y definidores para que en base a los nombres de campo. Si utiliza uno de estos captadores en otra clase, y luego decidir el campo está mal nombrado, no va a encontrar usos de los captadores y definidores y reemplazar el nombre antiguo con el nuevo nombre.

Me imagino que esto tendría que ser hecho a través de un IDE plug-in y no a través de Lombok.

ACTUALIZACIÓN (enero 22 de '13)
Después de usar Lombok durante 3 meses, todavía recomiendo que para la mayoría de los proyectos. Yo, sin embargo, parece otro inconveniente que es similar a la que aparece arriba.

Si usted tiene una clase, digamos MyCompoundObject.java que tiene 2 miembros, tanto anotado con @Delegate, myWidgets voz y myGadgets, cuando se llama myCompoundObject.getThingies() de otra clase, es imposible saber si se está delegando en el Widget o Gadget porque no puede ya salto a la fuente dentro del IDE.

Uso del Eclipse "Generar métodos de delegado ..." le proporciona la misma funcionalidad, es tan rápido y ofrece salto fuente. El inconveniente es que estorba su fuente con código repetitivo que apartar la atención de las cosas importantes.

ACTUALIZACIÓN 2 (feb 26 '13)
Después de 5 meses, todavía estamos utilizando Lombok, pero tengo algunas otras molestias. La falta de un captador y colocador declarado puede ser molesto a veces cuando se está tratando a familiarizarse con el nuevo código.

Por ejemplo, si veo un método llamado getDynamicCols() pero no sé de qué se trata, tengo algunos obstáculos adicionales para saltar para determinar los efectos de este método. Algunos de los obstáculos son Lombok, algunos son la falta de un plugin inteligente Lombok. Vallas incluyen:

  • Falta de JavaDocs. Si javadoc el campo, espero que el getter y setter heredaría que javadoc a través del paso de compilación Lombok.
  • Cambiar a la definición del método me salta a la clase, pero no la propiedad que ha generado el captador. Este es un tema plug-in.
  • Es obvio que no son capaces de establecer un punto de interrupción en un captador / definidor a menos que genere o código del método.
  • NOTA: Esta búsqueda de referencia no es un problema ya que lo primero que pensé que era. Usted necesita utilizar una perspectiva que permite la vista de esquema sin embargo. No es un problema para la mayoría de los desarrolladores. Mi problema era que estoy usando Mylyn que fue filtrando mi punto de vista Outline, por lo que no vi los métodos. falta de referencias búsqueda. Si quiero ver quién está llamando getDynamicCols(args...), tengo que generar o código de la incubadora para poder buscar referencias.

Actualización 3 (mar 7 '13)
Aprender a usar las distintas formas de hacer las cosas en Eclipse supongo. En realidad se puede establecer un punto de interrupción condicional (BP) en un método Lombok generado. Usando la vista Outline, puede hacer clic en el método para Toggle Method Breakpoint. Luego, cuando se pulsa el BP, se puede utilizar la vista Variables depuración para ver cuál es el método generado nombrado los parámetros (por lo general el mismo que el nombre de campo) y, por último, utilizar la vista Breakpoints hacer clic derecho en la BP y seleccione Breakpoint Properties... añadir Una condición. Niza.

ACTUALIZACIÓN 4 (agosto 16 de '13)
Netbeans no le gusta que cuando actualice sus dependencias Lombok en su POM Maven. El proyecto aún compila, pero los archivos se encuentra en posición de tener errores de compilación, ya que no puede ver los métodos de Lombok está creando. Borrado de la memoria caché Netbeans resuelve el problema. No estoy seguro si hay una opción de "Proyecto limpio" como hay en Eclipse. cuestión menor, pero quería darlo a conocer.

ACTUALIZACIÓN 5 (enero 17 de '14)
Lombok no siempre juega limpio con Groovy, o al menos la groovy-eclipse-compiler. Puede que tenga que rebajar su versión del compilador. Maven Groovy y Java + Lombok

ACTUALIZACIÓN 6 (jun 26 '14)
Una palabra de advertencia. Lombok es ligeramente adictivo y si se trabaja en un proyecto en el que no se puede utilizar, por alguna razón, se molestará a la orina fuera de usted. Usted puede ser mejor simplemente no usarlo en absoluto.

ACTUALIZACIÓN 7 (jul 23 '14)
Esto es un poco de una actualización interesante porque aborda directamente el seguridad de la adopción de Lombok que el PO preguntó sobre.

Como de v1.14, la anotación @Delegate se ha degradado a un estado experimental. Los detalles están documentados en su sitio ( Lombok Delegado Docs ).

La cosa es, si estuviera utilizando esta característica, sus opciones se limitan backout. Veo las opciones como:

  • eliminar manualmente las anotaciones @Delegate y generar / handcode el código delegado. Esto es un poco más difícil si estuviera usando atributos dentro de la anotación.
  • Delombok los archivos que tienen la anotación @Delegate y tal vez volver a agregar en las anotaciones que haga falta.
  • Nunca actualizar Lombok o mantener un tenedor (o en vivo con el uso de características experimentales).
  • Delombok todo el proyecto y dejar de usar Lombok.

Por lo que yo puedo decir, Delombok no tiene una opción para eliminar un subconjunto de anotaciones ; es todo o nada, al menos para el contexto de un solo archivo. Abrí un boleto para solicitar esta función con banderas Delombok, pero yo no esperaría que en un futuro próximo.

ACTUALIZACIÓN 8 (Octubre 20 '14)
Si se trata de una opción para usted, las ofertas más maravillosos de los mismos beneficios de Lombok, además de un barco de carga de otras características, incluyendo @Delegate . Si usted cree que tendrá dificultades para vender la idea a los poderes fácticos, echar un vistazo a la @CompileStatic o @TypeChecked anotación para ver si eso puede ayudar a su causa. De hecho, el enfoque principal de la liberación Groovy 2.0 era estático seguridad.

ACTUALIZACIÓN 9 (sep 1 '15)
Lombok todavía se está mantenido y mejorado , que es un buen augurio para el nivel de seguridad de adopción de forma activa. El @Builder anotaciones es una de mis nuevas funciones favoritas.

ACTUALIZACIÓN 10 (noviembre 17 de '15)
Esto puede no parecer directamente relacionada con la pregunta de la OP, pero vale la pena compartir. Si usted está buscando las herramientas para ayudarle a reducir la cantidad de código repetitivo que escribe, también se puede comprobar a cabo Google Auto - en particular, AutoValue . Si nos fijamos en su deslizante cubierta , una lista de Lombok como una posible solución al problema que se intenta resolver. Las desventajas que lista para Lombok son:

  • El código introducido es invisible (no se puede "ver" los métodos de los que genera) [Nota del editor - en realidad se puede, pero sólo requires un descompilador]
  • Los cortes compilador no son estándar y frágil
  • "En nuestra opinión, el código ya no es realmente Java"

No estoy seguro de cuánto estoy de acuerdo con su evaluación. Y teniendo en cuenta las desventajas de AutoValue que se documentan en las diapositivas, voy a estar pegando con Lombok (si es maravilloso no es una opción).

ACTUALIZACIÓN 11 (feb 8 '16)
Descubrí Spring Roo tiene algunos anotaciones similares . Yo estaba un poco sorprendidos al descubrir Roo sigue siendo una cosa y la búsqueda de documentación para las anotaciones es un poco peligrosa. La eliminación también no se ve tan fácil como de-Lombok. Lombok parece que la opción más segura.

ACTUALIZACIÓN 12 (feb 17 '16)
Al tratar de llegar a las justificaciones de por qué es seguro para llevar en Lombok para el proyecto Actualmente estoy trabajando, me encontré con una pieza de oro que se ha añadido con v1.14 - La Configuración del sistema ! Este es un medio que puede configurar un proyecto para dis-permitir que ciertas características que su equipo considere peligrosa o indeseable. Mejor aún, también puede crear configuración específica directorio con diferentes configuraciones. Esto es impresionante.

ACTUALIZACIÓN 13 (oct 4 '16)
Si este tipo de cosas es importante para usted, Oliver Gierke sintió que era seguro añadir a Lombok primavera de datos Resto .

ACTUALIZACIÓN 14 (sep 26 '17)
Como ha señalado @gavenkoa en los comentarios sobre la cuestión PO, apoyo compilador JDK9 todavía no está disponible (Edición # 985). También suena como que no va a ser una solución fácil para el equipo de Lombok a moverse.

ACTUALIZACIÓN 15 (mar 26 de '18)
La lista de cambios Lombok indica como de v1.16.20 " Compilación Lombok en JDK1.9 es posible ahora " a pesar de que # 985 todavía está abierta.

Los cambios para acomodar JDK9, sin embargo, requirió algunos cambios de ruptura; todos los aislados a los cambios en los valores predeterminados de configuración. Es un poco preocupante que introdujeron cambios de última hora, pero la versión única chocó el número de versión "Incremental" (que va desde v1.16.18 a v1.16.20). Desde este post era sobre la seguridad, si has tenido una yarn/npm como sistema de construcción que se actualiza automáticamente a la versión más reciente incrementales, es posible que en un rudo despertar.

ACTUALIZACIÓN 16 (ene 9 '19)

los problemas se han resuelto JDK9 y Lombok trabaja con JDK10, e incluso JDK11 tan lejos como pueda contar.

Una cosa que me di cuenta sin embargo que era concerniente a partir de un aspecto de la seguridad es el hecho de que el registro de cambios al pasar de v1.18.2 a listas v1.18.4 dos artículos como BREAKING CHANGE !? No estoy seguro de cómo romper un cambio ocurre en una actualización semver "parche". Podría ser un problema si se utiliza una herramienta que las versiones de las actualizaciones automáticas de parches.

Vaya por delante y el uso de Lombok, se puede hacer si es necesario "delombok" su código después http://projectlombok.org/features/delombok .html

En lo personal (y por lo tanto subjetivamente) que he encontrado que el uso de Lombok hace que mi código sea más expresiva de lo que estoy tratando de lograr cuando se compara con IDE / propias implementaciones de métodos complejos tales como código hash y los iguales.

Cuando utilizando

@EqualsAndHashCode(callSuper = false, of = { "field1", "field2", "field3" })

es mucho más fácil de mantener Iguales y HashCode consistente y no perder de vista que se evalúan los campos, que los IDE propia aplicación /. Esto es especialmente cierto cuando usted todavía va a añadir / quitar campos con regularidad.

Lo mismo vale para la anotación @ToString y sus parámetros que se comunican claramente el comportamiento deseado con respecto a los campos incluidos / excluidos, el uso de captadores o el acceso al terreno y tiempo o no a super.toString() llamada.

Y de nuevo al anotar una clase entera con @Getter o @Setter(AccessLevel.NONE) (y, opcionalmente, anulando cualquier métodos divergentes) que está inmediatamente claro qué estarán disponibles para los campos de métodos.

Los beneficios de seguir y seguir ..

En mi mente no se trata de la reducción de código, sino de la comunicación clara de lo que desea lograr, en lugar de tener que averiguarlo de Javadoc o implementaciones. El código reducida sólo hace que sea más fácil de detectar cualquier implementación divergente de métodos.

Lombok es grande, pero ...

Lombok rompe las reglas de procesamiento de anotación, ya que no genera nuevos archivos de origen. Esto significa que no puede ser utilizado con otro procesadores de anotación si esperan que los getters / setters o cualquier otra cosa para existir.

ejecuta el proceso de anotación en una serie de rondas. En cada ronda, cada uno tiene un turno para funcionar. Si se encuentran nuevos archivos de Java después de que se completó la ronda, comienza una nueva ronda. De esta manera, el orden de los procesadores de anotación no importa si sólo generan nuevos archivos. Desde Lombok no genera ningún archivo nuevo, ninguna nueva ronda se inician por lo que algunos de AP que se basa en código de Lombok no se ejecutan como se esperaba. Esta fue una gran fuente de dolor para mí durante el uso de mapstruct y delombok-ción no es una opción útil, ya que destruye los números de línea en los registros.

Finalmente he hackeado un script de construcción para trabajar tanto con Lombok y mapstruct. Pero quiero dejar Lombok, debido a la forma en hacky es - en este proyecto por lo menos. Yo uso Lombok todo el tiempo en otras cosas.

Hay mantenimiento a largo plazo riesgos también. En primer lugar, me gustaría recomendar la lectura acerca de cómo funciona realmente Lombok, por ejemplo, algunas respuestas de sus desarrolladores aquí .

El sitio oficial también contiene una lista de desventajas , incluyendo esta cita de Reinier Zwitserloot:

  

Es un corte total. El uso de la API no pública. de fundición presuntuosa (saber   que un procesador de anotación que se ejecuta en javac obtendrá una instancia de   JavacAnnotationProcessor, que es la implementación interna de   AnnotationProcessor (una interfaz), que por lo pasa a tener una pareja   de métodos adicionales que se utilizan para llegar a la AST en vivo).

     

En eclipse, es posiblemente peor (y aún más robusto) - un agente de Java   se utiliza para inyectar código en la gramática Eclipse y clase analizador,   que es de API supuesto totalmente no pública y totalmente fuera de los límites.

     

Si usted podría hacer lo que hace con Lombok API estándar, lo habría hecho   de esa manera, pero no se puede. Aún así, por lo que su valor, he desarrollado la   Eclipse plug-in para Eclipse v3.5 se ejecuta en Java 1.6, y sin   hacer cualquier cambio que trabajó en Eclipse v3.4 se ejecuta en Java 1.5 como   bien, así que no es completamente frágil.

A modo de resumen, mientras Lombok se puede ahorrar algo de tiempo de desarrollo, si hay una actualización javac no compatible (por ejemplo, una disminución de la vulnerabilidad) Lombok podría obtener atascado con una versión antigua de Java, mientras que los desarrolladores revuelven para actualizar su uso de las API internas. Si esto es un grave riesgo, obviamente, depende del proyecto.

He leído algunas opiniones sobre el Lombok y de hecho lo estoy usando en algunos proyectos.

Bueno, en el primer contacto con Lombok que tenía una mala impresión. Después de algunas semanas, empecé a gustar. Pero después de algunos meses que descubra una gran cantidad de pequeños problemas de usarlo. Por lo tanto, mi impresión final sobre Lombok no es tan positiva.

Mis razones para pensar de esta manera:

  • IDE plugin de dependencia . El soporte IDE para Lombok es a través de plugins. Incluso trabajando buenas ins mayor parte de las veces, usted es siempre un rehén de estos plugins se mantenga en las futuras versiones de los entornos de desarrollo y incluso la versión del idioma (Java 10+ acelerará el desarrollo de la lengua). Por ejemplo, he intentado poner al día a partir de IntelliJ IDE 2017,3 a 2.018,1 y yo no podía hacer eso porque hay algún problema en el Lombok real plug-in versión y tengo que esperar el plugin se actualiza ... Esto también es un problema si le gustaría utilizar un IDE más alternativa que no tienen ningún apoyo plugin de Lombok.
  • '' Encuentra usos problema. . El uso de Lombok no ve los captadores, organismo, constructores, métodos constructor generados y etc Por lo tanto, si usted está planeando para averiguar lo que de estos métodos están siendo utilizados en su proyecto por su IDE, no se puede hacer esto sólo en busca de la clase que posee los métodos de este ocultos.
  • Es tan fácil que los desarrolladores no les importa romper la encapsulación . Yo sé que no es realmente un problema de Lombok. Pero vi una mayor tendencia a los desarrolladores no controla más que las necesidades de los métodos que sean visibles o no. Por lo tanto, muchas veces no son más que copiar y pegar anotaciones @Getter @Setter @Builder @AllArgsConstructor @NoArgsConstructor sin pensar qué métodos de la clase realmente necesita para exponer.
  • Constructor Obssession ©. Inventé este nombre (bajar, Martin Fowler). Bromas aparte, un constructor es tan fácil de crear que, incluso cuando una clase tiene sólo dos parámetros de los desarrolladores prefieren usar @Builder en lugar de constructor o un método constructor estático. A veces, incluso tratan de crear un constructor dentro del constructor Lombok, creando situaciones extrañas como MyClass.builder().name("Name").build().create().
  • Barreras al refactorizar . Si está utilizando, por ejemplo, un @AllArgsConstructor y necesita agregar un parámetro más en el constructor, el IDE no puede ayudar a que usted agregue este parámetro adicional en todos los lugares (en su mayoría, pruebas) que se crear instancias de la clase.
  • Mezcla Lombok con métodos concretos . No se puede utilizar Lombok en todos los escenarios para crear un captador / definidor / etc. Así, verá estos dos enfoques mezclados en el código. Uno se acostumbra a esto después de algún tiempo, pero se siente como un corte en la lengua.

Al igual que otra respuesta, dijo, si está enfadado por el nivel de detalle de Java y Lombok utiliza para tratar con él, tratar Kotlin.

Sé que llego tarde, pero no puedo resistir la tentación: a nadie le gustaba Lombok también debe tener una mirada en Scala. Muchas ideas buenas que se encuentran en Lombok son parte del lenguaje Scala.

En la pregunta: ¿es definitivamente más fácil de conseguir sus desarrolladores tratan de Lombok Scala. Darle una oportunidad y si les gusta, trate de Scala.

Al igual que un descargo de responsabilidad: yo como Java, también

he utilizado Lombok en casi todos mis proyectos por un año, pero por desgracia quitado. En un principio fue una manera muy limpia de desarrollo, pero la configuración del entorno de desarrollo de nuevos miembros del equipo no es muy fácil y sencillo. Cuando se convirtió en un dolor de cabeza que se acaba de quitar. Pero se trata de una obra buena y necesita un poco más la simplicidad de la instalación.

Cuando me presenté el proyecto a mi equipo el entusiasmo era alto, así que creo que no debe tener miedo de la respuesta del equipo.

  • En cuanto a retorno de la inversión, es muy fácil de integrar, y no requiere cambio de código en su forma básica. (Sólo añadir una sola anotación a su clase)

  • Y por último, si usted cambia de opinión, puede ejecutar el unlombok, o dejar que su IDE crear estos organismos, captadores, y ctors, (que creo que nadie va a pedir una vez que vean cómo despejar su POJO se convierte en)

Se busca a @ToString uso de Lombok pero pronto se enfrentan errores de compilación al azar en proyectos de reconstrucción en IntelliJ IDEA. Tuvo que golpear compilación varias veces antes de la compilación gradual podría completar con éxito.

Probamos tanto lombok 1.12.2 y 0.9.3 con IntelliJ IDEA 12.1.6 y 13.0 sin ninguna lombok plugin de bajo JDK 1.6.0_39 y 1.6.0_45.

Tuvo que métodos manualmente copia generada a partir de fuente delomboked y poner lombok en espera hasta mejores tiempos.

Actualizar

El problema ocurre sólo con activar compilación paralela.

Archivado una cuestión: https://github.com/rzwitserloot/lombok/issues/648

Actualizar

  

mplushnikov comentó el 30 ene 2016:

     

versión más reciente de IntelliJ   no tiene este tipo de problemas más. Creo que se puede cerrar aquí.

Actualizar

I altamente recomendaría a cambio de Java + Lombok a Kotlin si es posible. Como se ha resuelto desde el principio todas las cuestiones de Java que Lombok intenta solucionar.

Mi opinión sobre Lombok es que se limita a establecer atajos para escribir bolilerplate código Java.
Cuando se trata de usar atajos para escribir bolilerplate código Java, que podría basarse en tales características proporcionadas por el IDE - al igual que en Eclipse, podemos ir al menú de fuente> Generar captadores y definidores para la generación de captadores y definidores
. Yo no depender de una biblioteca como Lombok para esto:

  1. Se contamina el código con una capa de direccionamiento indirecto de sintaxis alternativa (@Getter lectura, @Setter, etc. anotaciones). En lugar de aprender una sintaxis alternativa para Java, me gustaría cambiar a cualquier otra lengua nativa que proporciona Lombok sintaxis similar.
  2. Lombok requiere el uso de un IDE Lombok apoyado al trabajo con su código. Esta dependencia presenta un riesgo considerable para cualquier proyecto no trivial. ¿Tiene el proyecto de código abierto Lombok tiene suficientes recursos para mantener el apoyo a diferentes versiones de una amplia gama de de Java IDE disponible?
  3. ¿Tiene el proyecto de código abierto Lombok tiene suficientes recursos para mantener el apoyo a las nuevas versiones de Java que vendrán en el futuro?
  4. También se siente nervioso que Lombok puede introducir problemas de compatibilidad con bastidor / bibliotecas ampliamente utilizados (como Spring, Hibernate, Jackson, JUnit, Mockito) que trabajan con su código byte en tiempo de ejecución.

En suma, ¿no preferiría "darle vida" mi Java con Lombok.

he encontrado un problema con Lombok y Jackson CSV , cuando marshalized mi objeto (Java Bean) a un archivo CSV, columnas, donde duplicado, entonces me quita Lombok de @Data anotación y marshalizing bien trabajado.

No estoy recomiendo. Solía ??usar, pero luego cuando trabajo con NetBeans 7.4 se estaba metiendo mis códigos. Tengo para eliminar Lombok en todos los archivos en mis proyectos. Hay delombok, pero ¿cómo puedo estar seguro de que no sería atornillar mis códigos. Tengo que pasa días sólo para eliminar Lombok y de vuelta a los estilos comunes de Java. Acabo demasiado picante ...

No he intentado usar Lombok sin embargo - es / era el siguiente en mi lista, pero suena como si Java 8 ha causado problemas significativos para ello, y los trabajos de reparación aún estaba en curso a partir de hace una semana. Mi fuente para que sea https://code.google.com/p/ projectlombok / temas / detalle? id = 451 .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top