En algunos acentos del inglés, cuando dices «two for» muy rápido, suena como «two fer». Dos por uno es una forma de decir que si compras uno, te llevas otro gratis. Así que la expresión «two-fer» suele implicar una oferta de dos por uno.
Imagina una panadería que tiene una oferta de temporada en la que puedes comprar dos galletas al precio de una («two-fer one!»). Aceptas la oferta y (muy generosamente) decides darle la galleta extra a otra persona de la cola.
Tu tarea consiste en decidir qué vas a decir cuando regales la galleta extra.
Si conoces el nombre de la persona (por ejemplo, si se llama Do-yun), dirás:
One for Do-yun, one for me.
Si no conoces el nombre de la persona, en su lugar dirás you.
One for you, one for me.
Aquí tienes algunos ejemplos:
| Nombre | Diálogo |
|---|---|
| Alice | One for Alice, one for me. |
| Bohdan | One for Bohdan, one for me. |
| One for you, one for me. | |
| Zaphod | One for Zaphod, one for me. |
Odin admite argumentos predeterminados. Los argumentos predeterminados son una funcionalidad útil que permite llamar a un procedimiento con distintos conjuntos de parámetros para casos de uso en los que necesitas API relacionadas pero diferentes.
Sin argumentos predeterminados, podrías acabar con una explosión en el número de procedimientos necesarios para tu API. Los lenguajes que no admiten argumentos predeterminados, como Java, recurren a la sobrecarga de métodos para lograr el mismo efecto (con más código) o tienen que proporcionar procedimientos con, potencialmente, un gran conjunto de argumentos.
Veamos el ejemplo de un procedimiento greeting en el que queremos poder especificar el idioma, si el nombre va en mayúsculas y si debemos incluir un signo de exclamación al final del saludo.
Tras un análisis, descubrimos que el grupo más numeroso de usuarios especifica el inglés como idioma, no pone el nombre en mayúsculas y no quiere un signo de exclamación al final; el segundo grupo más numeroso añade un signo de exclamación al final del saludo.
Podríamos crear un único procedimiento con todos los argumentos:
greeting :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {
...
}
Esto obligaría a todos los usuarios a leer la documentación de todos los argumentos y a proporcionarlos siempre.
Sin argumentos predeterminados, también podríamos definir varios procedimientos con distintos conjuntos de parámetros:
greeting_common :: proc(name: string) {...}
greeting_with_exclamation :: proc(name: string) {...}
greeting_general :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {...}
// Odin supports overloading but it has to be explicitly defined
greeting :: proc {
greeting_common,
greeting_with_exclamation,
greeting_general,
}
Si tu lenguaje admite argumentos predeterminados, como hace Odin, puedes simplemente proporcionar valores predeterminados razonables a los argumentos menos usados. Quienes llaman pueden omitir los argumentos predeterminados, haciendo que el procedimiento use los valores predeterminados proporcionados, o sobrescribirlos.
greeting :: proc(name: string, language: Language = Language.English, do_uppercase : bool = false, add_exclamation: bool = false) {...}
// Note: because Odin supports type inference, we can simplify the interface.
greeting :: proc(name: string, language:= Language.English, do_uppercase := false, add_exclamation:= false) {...}
Se puede llamar al procedimiento con todos los argumentos predeterminados:
greeting("John Doe")
Los argumentos importantes para quien llama se pueden sobrescribir:
greeting("John Doe", Language.Spanish)
Si los argumentos que necesitas están en orden posicional, como en el ejemplo anterior, no hace falta nombrarlos como en el ejemplo anterior, pero si necesitas omitir algunos, tendrás que nombrar los argumentos después del primero que hayas omitido.
greeting("John Doe", add_exclamation=true)
En este ejercicio vas a implementar un procedimiento que debe reservar el string que devuelve. Liberar el string es responsabilidad de quien llama al procedimiento.
// The procedure will be called like that:
str := two_fer("Alice")
// ...
// and eventually the caller will delete the string
delete(str)
También puede interesarte la documentación oficial de Odin sobre argumentos predeterminados y los argumentos con nombre de Odin.
Regístrate en Exercism para aprender y dominar Odin con 73 ejercicios y mentoría humana real, todo gratis.