When you get user information in console, you might, sometimes, need to get sensible information. Password for example.
Which can’t be displayed on the screen for security reasons.
The library Ruby Password allows you to do that quite easily.
However it implies you depend on this library. And that’s something I don’t wish. Particularly for something so simple.

The solution I’m suggesting here uses the linux features (not tested on windows. But who’s still using it today ? :mrgreen: ).

begin
    print "Username: "
    username = $stdin.gets.chomp

    print "Password: "
    # We hide the entered characters before to ask for the password
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
rescue NoMethodError, Interrupt
    # When the process is exited, we display the characters again
    # And we exit
    system "stty echo"
    exit
end

What are we doing ?
We start by asking the user’s nickname.

print "Username: "
username = $stdin.gets.chomp

This is not a sensible data and can be displayed. Nothing specific to do.

Then we ask for a password. Here we must hide it.

print "Password: "
system "stty -echo"
password = $stdin.gets.chomp
system "stty echo"

The « stty -echo » will hide every character that should be displayed on the console.
The « stty echo » displays them again.

Until there is works. Cool !
But somehowe we have a boring user, whom decides at the last moment to enter Ctrl-C to quit the program and finds himself in console with the -echo mode and doesn’t see what he enters in. We’ve just lost a friend.

Fortunately we have exceptions notifications and we already detect an Interrupt to exit the program cleanly.
Then we just have to display the characters again when there’s this interrupt :)

begin
    # ...
rescue NoMethodError, Interrupt
    system "stty echo"
    exit
end

Hop ! :)
And the project that uses this is glynn :)

J’ai déjà mentionné la récupération d’informations par l’utilisateur en ruby console dans l’article Read Eval Print Loop.
Cependant il arrive qu’il soit nécessaire de récupérer des informations sensibles via la console. Un mot de passe par exemple. Celui-ci ne devra pas s’afficher sur l’écran pendant que vous le taperez.
La librairie Ruby Password permet de faire cela de manière simple.
Cependant cela implique dépendre de cette librairie. Et c’est quelque chose que je ne désire pas, surtout pour quelque chose d’aussi simple.

La solution que je vous propose ici utilise donc simplement les fonctionnalités de toute console linux (pas testé sous windows. Mais qui utilise encore windows de nos jours ? :mrgreen: ).

begin
    print "Username: "
    username = $stdin.gets.chomp

    print "Password: "
    # We hide the entered characters before to ask for the password
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
rescue NoMethodError, Interrupt
    # When the process is exited, we display the characters again
    # And we exit
    system "stty echo"
    exit
end

Que fait-on ?
Nous commençons par demander un nom d’utilisateur.

print "Username: "
username = $stdin.gets.chomp

Celui-ci n’est pas une donnée sensible et peut donc être affiché sans problème. Rien de particulier à faire.

Ensuite nous demandons un mot de passe. La il faut le masquer.

print "Password: "
system "stty -echo"
password = $stdin.gets.chomp
system "stty echo"

Le « stty -echo » masquera tous les caractères qui devraient être affichés en console par la suite.
Le « stty echo » permet d’afficher les caractères qui seront tapés ensuite.

Jusque la, ça fonctionne. Cool !
Mais d’un coup j’ai un utilisateur chiant (oui toi là-bas à côté du radiateur), qui décide au dernier moment de faire Ctrl-C pour quitter le programme et se retrouve dans une console en -echo et ne voit donc plus ce qu’il tape. On vient pas de se faire un ami.

Heureusement on gère l’arrêt du système notre rescue, ou l’on indique que lorsqu’un Ctrl-C est envoyé, on désire quitter l’application.
Lorsque c’est le cas, nous n’avons donc plus qu’à également réafficher les caractères et le tour est joué !

begin
    # ...
rescue NoMethodError, Interrupt
    system "stty echo"
    exit
end

Hop ! :)
Et le projet qui utilise ceci, c’est glynn :)

 
Fork me on GitHub