2012-03-27 45 views
4

我試圖使用以下代碼在文件中接受作爲終端中的參數,然後它將讀取並更新body變量及其內容。如果文件沒有被傳入,那麼我想讓用戶輸入他們自己的正文副本的提示。將命令行參數接收到Ruby腳本中


require 'posterous' 

Posterous.config = { 
    'username' => 'name', 
    'password' => 'pass', 
    'api_token' => 'token' 
} 

include Posterous 
@site = Site.primary 

#GETS POST TITLE 
puts "Post title: " 
title = STDIN.gets.chomp() 

if defined?(ARGV) 
    filename = ARGV.first 
end 

if (defined?(filename)) 
    body = File.open(filename) 
    body = body.read() 
else 
    puts "Post body: " 
    body = STDIN.gets.chomp() 
end 
puts body 

當我沒有通過的文件中運行該程序我得到這個返回:


Post title: 
Hello 
posterous.rb:21:in `initialize': can't convert nil into String (TypeError) 
    from posterous.rb:21:in `open' 
    from posterous.rb:21:in `' 

我是相當新的紅寶石,因此不是最好的吧。我嘗試交換了很多東西,改變了一些東西,但無濟於事。我究竟做錯了什麼?

回答

10

defined?(ARGV)將不會返回布爾值false,而是"constant"。由於這不會評估爲false,filename被定義爲ARGV[0],即nil

>> ARGV 
=> [] 
>> defined?(ARGV) 
=> "constant" 
?> ARGV.first 
=> nil 

相反,你可能要檢查的ARGV長度:

if ARGV.length > 0 
    filename = ARGV.first.chomp 
end 

From the docs:

定義?表達式測試表達式是否指任何可識別的東西(文字對象,已初始化的局部變量,方法名稱可從當前範圍中看到,等等)。如果表達式無法解析,返回值爲零。否則,返回值提供有關表達式的信息。

2

邁克爾給了你的問題的基本答案。比較魯比斯式的做法是使用ARGF來進行閱讀;那麼條件只需要決定是否要打印提示:

puts "Post title: " 
title = gets.chomp 

puts "Post body: " if ARGV.length == 0 
body = ARGF.gets.chomp 
puts body 

..of當然,如果你不需要任何其他與身體,你可以跳過存儲文件的內容( s),只是做

puts ARGF.gets.chomp