Introducción
La migración de un proyecto a un nuevo lenguaje de programación puede ser una tarea difícil y lenta. GitHub Copilot puede ayudarte con este proceso explicando los cambios que necesitas realizar y sugiriendo código de reemplazo en el nuevo lenguaje.
Principios de migración de un proyecto a un nuevo lenguaje
Ten en cuenta los puntos antes de iniciar un proceso de migración:
-
Conocimientos de codificación
Asegúrate de tener una buena comprensión de ambos lenguajes de programación. Aunque Copilot puede traducir código automáticamente, debes comprender las opciones que propone y decidir si deseas usar sus sugerencias o solicitar una sugerencia alternativa.
-
Conocimientos del sistema que vas a migrar
Asegúrate de comprender la arquitectura y la lógica del sistema actual, además de las funciones y características que proporciona a los usuarios. Debes poder comprobar que el código traducido realiza todas las mismas operaciones que el código original y genera los mismos resultados.
-
Uso de la inteligencia artificial para ayudarte
Si no entiendes una parte concreta del código que estás a punto de traducir, usa la característica "explicar" de Copilot, ya sea en todo el archivo o en una parte seleccionada del código dentro de un archivo. Consulta Preguntas sobre GitHub Copilot en el IDE.
-
Programar la hora de finalización de la migración
La conversión es un proceso de varias fases. Cuanto mayor sea el proyecto que vas a convertir, mayor será el número de pasos que tendrás que realizar. Asegúrate de tener el suficiente tiempo para completar todo el proceso.
-
Trabajar iterativamente
Intenta convertir partes discretas del proyecto por separado. Asegúrate de haber comprobado todos los cambios realizados antes de pasar a otra parte del proyecto. Escribe pruebas para las partes individuales del proyecto a medida que continúas para que puedas confirmar que cada uno de los nuevos componentes funciona según lo previsto.
-
Evitar la introducción de complejidad en el proceso
Inicialmente, debes tener como objetivo realizar una conversión similar al original. Esto no será posible para todo el código del proyecto. Sin embargo, para evitar agregar complejidad a la tarea de migración, debes intentar limitar el número de cambios nuevos que se introducen, aparte de traducir el código y usar un nuevo marco y las dependencias adecuadas.
-
Prueba comparativa y refactorización del código traducido
Una vez que hayas completado la conversión inicial y tengas un sistema funcional, puedes realizar pruebas comparativas para comparar los sistemas antiguos y nuevos. Ahora puedes refactorizar el código en el nuevo lenguaje. Esta es una oportunidad para optimizar el código y reducir la deuda técnica.
Uso de Copilot para ayudarte a migrar un proyecto a un nuevo lenguaje
Suponiendo que ya te has familiarizado con el proyecto existente, una buena manera de iniciar una migración es abrir una rama del repositorio en el editor y pedir ayuda a Copilot.
-
En el editor, abre el panel de Copilot Chat. Consulta Preguntas sobre GitHub Copilot en el IDE.
-
Pide a Copilot que describa los pasos que debes seguir para migrar el proyecto al nuevo lenguaje.
Por ejemplo, para una migración de PHP a Python, podrías preguntar:
@workspace I want to migrate this project from PHP to Python. Give me a high level overview of the steps I need to take. Don't go into detail at this stage.
Note
El participante del chat
@workspace
establece los archivos en el área de trabajo actual como contexto de la pregunta que se formula.Copilot normalmente aportará una lista de pasos que debes realizar para migrar el proyecto.
-
Copie la respuesta de Copilot y guárdala en algún lugar para consultarla durante el proceso.
-
Sigue cada paso del proceso y solicita ayuda detallada de los datos Copilot según lo necesites.
Considera cada sugerencia de Copilot cuidadosamente. Asegúrate de comprender el código que sugiere y evalúa si es adecuado para el proyecto. Si no estás seguro, pide a Copilot que te explique el código.
Si crees que un cambio sugerido por Copilot no es correcto de alguna manera, solicita una sugerencia alternativa.
-
En cuanto hayas migrado un componente a un estado que puedas ejecutar, comprueba que funciona según lo previsto. Si se genera un error, copia el error en la vista de Copilot Chat y pide a Copilot que te ayude a corregirlo.
-
Una vez completada la conversión inicial, usa Copilot para ayudarte a refactorizar el código en el nuevo lenguaje. Para más información, consulta Refactorización de código con GitHub Copilot.
Ejemplo: migración de un proyecto PHP a Python
En el ejemplo siguiente se describe la migración de una aplicación web sencilla de PHP a Python. Incluso si no son los lenguajes de programación que usas para la migración, puede resultarte útil seguir los pasos descritos aquí para familiarizarte con una migración del proyecto. Los pasos serán similares para migrar otros proyectos pequeños de un lenguaje a otro.
En este ejemplo se da por supuesto que:
- Trabajas en Visual Studio Code.
- Tienes instalados ambos lenguajes: PHP y Python versión 3.12 o posterior.
Migración de un proyecto de sitio web sencillo
Vamos a migrar el código de este repositorio público en GitHub: docs/simple-php-website.
El repositorio consta de los siguientes archivos.
.gitignore
.htaccess
LICENSE
content
├── 404.phtml
├── about-us.phtml
├── contact.phtml
├── home.phtml
└── products.phtml
includes
├── config.php
└── functions.php
index.php
readme.md
template
├── style.css
└── template.php
En este ejemplo se proporcionan las indicaciones que puedes escribir en Copilot Chat para completar la migración y las respuestas de Copilot devueltas para una instancia de esta migración. Las respuestas de Copilot Chat no son deterministas, por lo que probablemente obtendrás respuestas ligeramente diferentes a las que se muestran aquí.
Durante un proceso de migración, es probable que obtengas errores que debes corregir antes de continuar. Copilot puede ayudarle con esto. En el ejemplo se incluyen algunos errores y se muestra cómo puedes hacer que Copilot te ayude a corregirlos.
Dado que es probable que las respuestas que obtengas de Copilot Chat sean diferentes a las que se muestran aquí, es posible que encuentres errores diferentes. Por lo tanto, es más fácil recorrer este ejemplo de migración mediante las respuestas que se muestran aquí, en lugar de las que obtienes de Copilot tú mismo.
Después de completar esta migración de ejemplo, puedes usar la misma metodología en tu propio proyecto.
-
Empieza por clonar una copia del repositorio en el equipo local.
-
Ejecuta la aplicación para comprobar que funciona.
Para ello, en un terminal, ve a la raíz del repositorio clonado y ejecuta el siguiente comando:
Shell php -S localhost:8000
php -S localhost:8000
A continuación, en un explorador, ve a: http://localhost:8000.
-
Haz clic en el sitio web para examinarlo, de modo que puedas comprobar que la migración se ha realizado correctamente.
-
Crea una rama de trabajo en el repositorio y ábrela como una nueva área de trabajo en Visual Studio Code.
-
Familiarízate con el contenido y la arquitectura del proyecto existente. Copilot puede ayudarle con esto:
-
Abre la vista de Copilot Chat.
-
Escribe una indicación como:
@workspace Describe this project in detail, explaining what the various components do and how they interact.
-
-
Pregunta a Copilot para obtener información general de alto nivel del proceso de migración:
@workspace I want to migrate this project from PHP to Python. Give me a high level overview of the steps I need to take. Don't go into detail at this stage.
Copilot responderá con instrucciones como:
To migrate this project from PHP to Python, follow these high-level steps: 1. Set Up Python Environment: - Install Python and set up a virtual environment. - Install necessary packages (e.g., Flask for web framework). 2. Convert Configuration: - Translate the configuration settings from config.php to a Python configuration file. 3. Rewrite Functions: - Convert PHP functions in functions.php to Python functions. 4. Create Flask Application: - Set up a Flask application to handle routing and views. - Map the routes to corresponding views. 5. Convert Templates: - Translate template.php to a Jinja2 template. - Update the CSS file path in the template. 6. Convert Content Pages: - Convert .phtml content files to HTML or Jinja2 templates. 7. Update .htaccess Rules: - Translate .htaccess rewrite rules to Flask route handling. 8. Run and Test: - Run the Flask application and test all routes and functionalities. - Ensure the site works as expected and fix any issues. 9. Documentation: - Update the readme.md with new instructions for running the Python project.
-
Copie la respuesta de Copilot y guárdala en algún lugar para consultarla durante el resto de este proceso. Trabajarás en cada uno de estos pasos, solicitando a Copilot que te ayude a medida que progreses.
-
Si aún no has decidido qué marco de Python deseas usar, puedes pedir a Copilot que te aconseje:
@workspace What Python frameworks can I use for this project once it is migrated to Python? Give me a selection of options, with a brief summary of the pros and cons of each in relation to this website project. Which framework would you recommend?
Copilot responde con información sobre varios marcos y concluye:
For a project like yours - which is a simple, content-driven website - Flask is highly recommended. Its simplicity, flexibility, and ease of use (especially with its templating system that can easily replace your current PHP template structure) make it a great fit.
Seguiremos los consejos de Copilot y usaremos Flask.
-
De vuelta en la información general de alto nivel de Copilot, el primer paso es configurar un entorno de Python e instalar los paquetes necesarios. Para averiguar cómo hacerlo, en Copilot Chat, escribe:
@workspace I want to use Flask. Tell me how to set up a virtual environment and install the necessary packages.
Copilot responderá con instrucciones como:
1. Create a virtual environment: - Open a terminal and navigate to your project directory. - Run the following command to create a virtual environment: python3 -m venv venv 2. Activate the virtual environment: - On macOS and Linux: source venv/bin/activate - On Windows: venv\Scripts\activate 3. Install Flask and necessary packages: - With the virtual environment activated, run the following command to install Flask and other necessary packages: pip install Flask 4. Verify the installation: - You can verify that Flask is installed by running: pip list
-
Sigue las instrucciones de Copilot y usa
pip list
para comprobar que Flask está instalado. -
De vuelta en la información general de Copilot para el proceso de migración, el siguiente paso es convertir la configuración. Pregunta a Copilot para obtener ayuda con esto. Por ejemplo:
@workspace As the first step in migrating this project from PHP to Python, create a Python configuration file by converting the functions in functions.php to Python functions. Tell me where to locate the Python config file in the project.
Copilot sugiere que crees un archivo denominado
config.py
en el directorioincludes
, que contiene el código siguiente.Python config = { 'name': 'Simple Python Website', 'site_url': '', 'pretty_uri': False, 'nav_menu': { '': 'Home', 'about-us': 'About Us', 'products': 'Products', 'contact': 'Contact', }, 'template_path': 'template', 'content_path': 'content', 'version': 'v3.1', } def get_config(key=''): return config.get(key, None) def site_name(): return get_config('name') def site_url(): return get_config('site_url') def site_version(): return get_config('version') def nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) def page_title(): page = request.args.get('page', 'Home') return ' '.join(word.capitalize() for word in page.split('-')) def page_content(): page = request.args.get('page', 'home') path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def init(): template_path = os.path.join(get_config('template_path'), 'template.html') with open(template_path, 'r') as file: return file.read()
config = { 'name': 'Simple Python Website', 'site_url': '', 'pretty_uri': False, 'nav_menu': { '': 'Home', 'about-us': 'About Us', 'products': 'Products', 'contact': 'Contact', }, 'template_path': 'template', 'content_path': 'content', 'version': 'v3.1', } def get_config(key=''): return config.get(key, None) def site_name(): return get_config('name') def site_url(): return get_config('site_url') def site_version(): return get_config('version') def nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) def page_title(): page = request.args.get('page', 'Home') return ' '.join(word.capitalize() for word in page.split('-')) def page_content(): page = request.args.get('page', 'home') path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def init(): template_path = os.path.join(get_config('template_path'), 'template.html') with open(template_path, 'r') as file: return file.read()
-
Cree el archivo
includes/config.py
y elimina el archivoincludes/config.php
existente. -
Vuelve a la información general de nuevo, pide a Copilot que te ayude a volver a escribir las funciones PHP.
@workspace Continuing the migration of this project from PHP to Python, create Python functions to replace the existing PHP functions. Tell me where to locate the Python functions in the project.
Copilot sugiere crear un archivo denominado
functions.py
en el directorioincludes
, que contiene el código siguiente.Python import os from flask import request from .config import get_config def site_name(): return get_config('name') def site_url(): return get_config('site_url') def site_version(): return get_config('version') def nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) def page_title(): page = request.args.get('page', 'Home') return ' '.join(word.capitalize() for word in page.split('-')) def page_content(): page = request.args.get('page', 'home') path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def init(): template_path = os.path.join(get_config('template_path'), 'template.html') with open(template_path, 'r') as file: return file.read()
import os from flask import request from .config import get_config def site_name(): return get_config('name') def site_url(): return get_config('site_url') def site_version(): return get_config('version') def nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) def page_title(): page = request.args.get('page', 'Home') return ' '.join(word.capitalize() for word in page.split('-')) def page_content(): page = request.args.get('page', 'home') path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def init(): template_path = os.path.join(get_config('template_path'), 'template.html') with open(template_path, 'r') as file: return file.read()
-
Cree el archivo
includes/functions.py
y elimina el archivoincludes/functions.php
existente. -
Siguiendo con la información general, el siguiente paso es crear una aplicación de Flask. Pide a Copilot que te ayude con esto:
@workspace Set up a Flask application to handle routing and views, and map the routes to corresponding views. Tell me the location of any files that need to be created or changed.
Copilot sugiere crear un archivo denominado
app.py
en la raíz del proyecto, que contiene el código siguiente.Python from flask import Flask, render_template, request import os app = Flask(__name__) config = { 'name': 'Simple Python Website', 'site_url': '', 'pretty_uri': False, 'nav_menu': { '': 'Home', 'about-us': 'About Us', 'products': 'Products', 'contact': 'Contact', }, 'template_path': 'template', 'content_path': 'content', 'version': 'v3.1', } def get_config(key=''): return config.get(key, None) @app.route('/') @app.route('/<page>') def index(page='home'): page_content = get_page_content(page) page_title = get_page_title(page) nav_menu = get_nav_menu() return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu) def get_page_title(page): return ' '.join(word.capitalize() for word in page.split('-')) def get_page_content(page): path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def get_nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) if __name__ == '__main__': app.run(debug=True)
from flask import Flask, render_template, request import os app = Flask(__name__) config = { 'name': 'Simple Python Website', 'site_url': '', 'pretty_uri': False, 'nav_menu': { '': 'Home', 'about-us': 'About Us', 'products': 'Products', 'contact': 'Contact', }, 'template_path': 'template', 'content_path': 'content', 'version': 'v3.1', } def get_config(key=''): return config.get(key, None) @app.route('/') @app.route('/<page>') def index(page='home'): page_content = get_page_content(page) page_title = get_page_title(page) nav_menu = get_nav_menu() return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu) def get_page_title(page): return ' '.join(word.capitalize() for word in page.split('-')) def get_page_content(page): path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml') if not os.path.exists(path): path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml') with open(path, 'r') as file: return file.read() def get_nav_menu(sep=' | '): nav_menu = '' nav_items = get_config('nav_menu') for uri, name in nav_items.items(): query_string = request.args.get('page', '') class_active = ' active' if query_string == uri else '' url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}" nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}' return nav_menu.strip(sep) if __name__ == '__main__': app.run(debug=True)
Copilottambién sugiere cambiar el nombre
template/template.php
atemplate/template.html
y actualizar el archivo para usar la sintaxis de plantillas Jinja2:HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="x-ua-compatible" content="ie=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> <title>{{ page_title }} | {{ get_config('name') }}</title> <link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="wrap"> <header> <h1>{{ get_config('name') }}</h1> <nav class="menu"> {{ nav_menu|safe }} </nav> </header> <article> <h2>{{ page_title }}</h2> {{ page_content|safe }} </article> <footer> <small>©{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small> </footer> </div> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="x-ua-compatible" content="ie=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> <title>{{ page_title }} | {{ get_config('name') }}</title> <link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="wrap"> <header> <h1>{{ get_config('name') }}</h1> <nav class="menu"> {{ nav_menu|safe }} </nav> </header> <article> <h2>{{ page_title }}</h2> {{ page_content|safe }} </article> <footer> <small>©{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small> </footer> </div> </body> </html>
-
Crea los archivos
app.py
ytemplate/template.html
como se sugiere. -
Copilot también puede sugerir que, después de crear estos archivos, ahora ejecutes
python app.py
en el terminal, desde la raíz del repositorio y, a continuación, vayas a http://127.0.0.1:5000.Note
En función de cómo esté instalado Python en el equipo, es posible que tengas que usar el comando
python3 app.py
en lugar depython app.py
para asegurarte de que se usa la versión correcta de Python.Al hacerlo, verás mensajes de error en el explorador.
-
Copia el mensaje de error inicial
TemplateNotFound
en la vista de Copilot Chat y pregunta cómo puedes corregirlo. Por ejemplo:@workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.TemplateNotFound: template.html`. How can I fix this?
Copilot responde que el error indica que Flask no puede localizar el archivo
template.html
.Indica que, de forma predeterminada, Flask busca plantillas en una carpeta denominada
templates
en el directorio raíz del proyecto. Sin embargo, el archivotemplate.html
se encuentra en el directoriotemplate
. Para corregirlo, debes especificar la carpeta de plantilla correcta al crear la aplicación Flask. Te aconseja actualizar el archivoapp.py
y cambiar la asignaciónapp = Flask(__name__)
para incluir el parámetrotemplate_folder
:Python app = Flask(__name__, template_folder='template')
app = Flask(__name__, template_folder='template')
-
Suponiendo que el servidor de desarrollo de Flask todavía se esté ejecutando, si actualizas la página del explorador en http://127.0.0.1:5000/, ahora verás un nuevo error relacionado con la función
get_config
.Copia este mensaje de error en la vista Copilot Chat y solicita ayuda.
@workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.UndefinedError: 'get_config' is undefined.` How can I fix this?
Copilot responde que se produce el error porque
get_config
no está disponible en el contexto de plantilla Jinja2. Te aconseja agregar el código siguiente al archivoapp.py
, directamente antes de la línea@app.route('/')
:Python app.jinja_env.globals.update(get_config=get_config)
app.jinja_env.globals.update(get_config=get_config)
-
Actualiza el explorador y ahora deberías ver el sitio web.
Sin embargo, no se aplica ninguno de los estilos CSS. Lo corregiremos a continuación.
-
Pregunta a Copilot:
@workspace The deployed website does not use the CSS styles. How can I fix this?
Copilot indica que Flask espera que el archivo CSS esté en un directorio denominado
static
. Sugiere mover el archivostyle.css
existente del directoriotemplate
a un nuevo directoriostatic
y, a continuación, actualizar la ruta de acceso al archivostyle.css
dentro de la partehead
del archivotemplate.html
. Cambia esto a:HTML <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
Al actualizar el explorador, el sitio web ahora debería representarse correctamente.
Para completar la migración inicial, sigue trabajando en los pasos descritos en la introducción general de alto nivel que Copilot te dio, solicitando ayuda cuando lo necesites.
Finalización de la migración
El trabajo adicional para completar correctamente el proceso de migración implicaría lo siguiente:
- Comprobación exhaustiva de la migración inicial.
- Corrección de errores. Por ejemplo, en la actualidad en el ejemplo descrito aquí, los vínculos de página solo funcionan si estableces
pretty_uri
enTrue
en la secciónconfig
del archivoapp.py
. Si deseas usar parámetros de cadena de consulta en las direcciones URL de la página o si deseas quitar esta opción del código, puedes pedir a Copilot que te ayude a hacerlo. - Escribe pruebas para el proyecto migrado.
- Limpia el proyecto, quita los archivos que ya no sean necesarios.
- Refactoriza el código en el nuevo lenguaje. El proceso de migración ha dado lugar a un proyecto de Python cuya arquitectura se basa en la del proyecto PHP original. Después de realizar la migración inicial, ahora puedes refactorizar el código para aprovechar mejor las características del lenguaje Python y el marco de Flask.
- Actualización de la documentación. El archivo
readme.md
ya no está actualizado y debe volver a escribirse.