One of the exercises I like to program when learning a new language is a chat client for the console. I've programmed it in many languages (Perl, Python, C, C++, JavaScript, ...). One of the versions I like most for its terseness is Ruby:
#!/usr/bin/ruby
require 'socket'
s = TCPSocket.new(ARGV[0], ARGV[1].to_i)
nick = ARGV[2]
# send nick to server
s.puts(nick)
# input thread
kbd = Thread.new {
STDIN.each_line { |line|
s.puts("\033[31m" + nick + "> " + "\033[0m" + line)
}
s.close_write
}
# output thread
con = Thread.new {
s.each_line { |line|
STDOUT.puts(line)
}
}
kbd.join
con.join
The initial Rust equivalent would be something similar to:
use std::os;
use std::io;
use std::io::{TcpStream, BufferedReader};
fn main() {
let args = os::args();
let mut s = TcpStream::connect(args[1], from_str(args[2]));
// send nick to server
nick = args[3];
s.write_line(nick);
// input thread
spawn(proc() {
for line in io::stdin().lines() {
s.write_str(format!("\x1b[31m{}> \x1b[0m{}", nick, line));
}
s.close_write();
});
// output thread
spawn(proc() {
for line in BufferedReader::new(s).lines() {
io::stdout().write_str(line);
}
});
}
which obviously has some compile errors. The corrected version is:
use std::os;
use std::io;
use std::io::{TcpStream, BufferedReader};
fn main() {
let args = os::args();
let mut s = TcpStream::connect(args[1].as_slice(),from_str(args[2].as_slice()).unwrap()).unwrap();
// send nick to server
s.write_line(args[3].as_slice()).unwrap();
let nick = args[3].clone();
let mut sin = s.clone();
// input
spawn(proc() {
for line in io::stdin().lines() {
sin.write_str(format!("\x1b[31m{}> \x1b[0m{}", nick, line.unwrap().as_slice()).as_slice()).unwrap();
}
sin.close_write().unwrap();
});
// output
spawn(proc() {
for line in BufferedReader::new(s).lines() {
io::stdout().write_str(line.unwrap().as_slice()).unwrap();
}
});
}
That's too verbose, isn't it? Perhaps it's due to the fact that the compiler is still beta (0.12-nightly)? Can this terseness be simplified?
sin.write_str(format!("\x1b[31m{}> \x1b[0m{}", nick, line.unwrap().as_slice()).as_slice()).unwrap();
would be better written(write!(sin, "\x1b[31m{}> \x1b[0m{}", nick, line.unwrap())).unwrap()
. – Chris Morgan Oct 6 '14 at 1:01(write!(io::stdout(), "{}", line.unwrap())).unwrap();
as well – francesc Oct 6 '14 at 9:05