Ruby File.open 等若干 File 的操作

jialezhang · 2012年06月15日 · 最后由 odinsolo 回复于 2013年01月16日 · 7663 次阅读

最近学习 ruby 的基本语言,在使用 ruby 的 File.open 读取文件的时候突然出问题了 代码如下

filename = ARGV.first

prompt = "> "
txt = File.open(filename)

puts "Here's your file: #{filename}"
puts txt.read()

puts "Type the filename again:"
print prompt
file_again = STDIN.gets.chomp()

txt_again = File.open(file_again)

puts txt_again.read()

然后终端执行的时候报错


some.rb:4:in `initialize': can't convert nil into String (TypeError)
    from some.rb:4:in `open'
    from some.rb:4:in `<main>'

请问是我的 ruby 没有安装好还是什么,求指教

你的参数明显没有传导致的。遇到这种情况,请直接看 some.rb:4 这个 4 很关键。

#1 楼 @lyfi2003 4 不就是指的第 4 行么 就是 txt = File.open(filename) 这句,我刚刚开始以为是自己的代码有问题,但是我从网站上面 copy 下来还是一样的
于是我执行 ri Fiie.open 时 shell 报的是

jialezhang@jialezhang-Lenovo-G460:~/ror$ ri File.open
Nothing known about File.open

can't convert nil into String

filename is nil

看第一行,应该是没有从命令行传入文件名参数

楼主可能没理解这一行的意思 filename = ARGV.first

PS: 使用权 File.open,直接接 block,这样能保证 close,就不用自己 close 了。

文件名输入正确吗?路径?

#5 楼 @fsword 那个不是读取文件名的么,由于学的时间不是特别的久,自己之前也搜了下,还不是很能明白,不知可不可以指教下

#6 楼 @zhenning 不懂 block&close 啊 求指教

#7 楼 @zhangyan 请问这个文件名是指哪里的啊

#9 楼 @jialezhang 貌似懂了一点点,出现我预期的的结果,但是不知道您的懂是什么水平

#3 楼 @Rei 就是说我没在后面输入文件的名字不?

#9 楼 @jialezhang 执行一个脚本时可以携带参数,这个 ARGV 就是你在脚本中使用参数的方法

~ $ cat a.rb
puts ARGV
puts ARGV.length
~ $ ruby a.rb a b c
a
b
c
3

#17 楼 @fsword 谢谢你啦,对这个有了进一步的了解了哈 嘿嘿

#18 楼 @jialezhang 对初学者来说,理解清楚下面几个基本概念会对学习有帮助的:当前工作目录、环境变量、命令行参数、进程的标准输出/标准错误、进程的返回值 在计算机上做的任何事都可以问问自己上面的名词在这里指什么,不管学习什么语言,我都建议弄清楚这些知识

#12 楼 @jialezhang

你没有给 argv 提供参数,当然会出错啦。

你试试运行 : xxx.rb 一个文件名。

#21 楼 @lb563 你是特别懂 block 的含义,但是我会慢慢的通过网上的资源去学习~ thx 啦

#22 楼 @zw963 想请问下 nginx+passenger 的配置有 wiki 没有啊

#25 楼 @jialezhang

目前还没接触过。咱们的 wiki 上不是有么。http://ruby-china.org/wiki/mac-nginx-passenger-rails 另外敏捷开发第四版你看过吗?有一章专门讲这个东西。你可以下载一个电子版来看。

#25 楼 @jialezhang 有一篇 wiki,可以参考一下,主要是搞明白其中得原理就简单了。 http://ruby-china.org/wiki/mac-nginx-passenger-rails

#26 楼 @zw963 书看了一部分,书上看了这个 passenger 的部分,但是还是没解决问题。重装过几次,单纯使用passenger-instal-nginx-module时,往/usr/local/nginx 里面装 nginx 时会有权限问题,但是使用sudo passenger-install-nginx-module会进入超级用户的权限,普通用户的文件系统和超级用户的是不一样的,之前我是进到/home/jialezhang/.rvm/gems/ruby-1.9.3p194/gems/passenger-1x.x.x/bin/执行sudo ./passenger-install-nginx-module成功安装上 nginx 的,然后就出现问题,解决不了 ps:我的 myapp/public 下面如果有 index.html 文件就会正确的显示了

#27 楼 @lgn21st 我有从你的博客上面看到这个,然后有人评论出现了和我类似的问题额,解决不了

#29 楼 @jialezhang wiki 和我得 blog 上都没有涉及道权限方面得问题,是因为如果按照 wiki 上得操作顺序,是没有权限问题的。完全不需要以 sudo 的方式来安装 passenger-instal-nginx-module,只需要以 sudo 来启动 nginx 到 80 端口即可,如果不是要启动到 80 端口,sudo 都不需要。

权限这个东西很复杂么?我觉得是非常简单的概念呀,奇怪的是 passenger 的权限问题挡住了这么多人,看来是需要找个时间专门写一篇关于如何处理权限的 wiki 了。

没有 sudo 的结果 Please specify a prefix directory [/opt/nginx]: /usr/local/nginx

Permission problems

This installer must be able to write to the following directory:

/usr/local/nginx

But it can't do that, because you're running the installer as jialezhang.

Please re-run this installer as root.

然后就只有sudo passenger-install-nginx-module了,然后估计就导致了后面的 forbidden 了

检查一下 /usr/local 这个目录的权限,我想你的问题在这里。应该是是可以创建目录并写入的。

#30 楼 @lgn21st

赶紧写出来呀。我也看看. #29 楼 @jialezhang

可能就是@lgn21st 所说的用户权限问题吧。我现在对于部署,还没考虑过呢。汗~

我发现我专门认真的学过 linux, 真是一个明智的选择...

#32 楼 @lgn21st 我改了/usr/local 的权限,让它有了写了权限,passenger-install-nginx-module,的确是可以安上去的,但是最后启动 nginx 时,错误的日志首先说Insecure world writable /usr/local/sbin,关掉它的写权限后,又报错`Insecure world writable /usr/local,我想不是每个文件夹的都可以把写的权限删除吧,写到这个地方,我还是冒着电脑出问题的风险把/usr/local 的写权限删除了,重启 ngnix,我的天呐!居然还是 forbidden,nginx 的错误日志里面权限的问题没有了,但是后面的Index of myapp/public is forbidden(里面没有说 permission denied),stack over flow 上面有一样的问题,但是他是忘了写passenger_root&&passenger_ruby,求教啊

#33 楼 @zw963 这个,@lgn21st说的权限问题我全部改过了额,目前测试没有用

我想你方向对了,但是目录的权限没有完全改对,但是我不知道怎么描述给你应该如何修改,你只要一直这么折腾下去,你最终会折腾出来的,这个我倒是很有信心。

我建议你这样,试试看把 nginx 装到自己的当前用户目录下吧,比如 ~/dev/nginx 然后就没有 /usr/local 什么事情了,用 sudo 直接去启动 ~/dev/nginx/sbin/nginx 即可,也不用去做 symbol link 了,这样大概就能绕过权限问题了。

#36 楼 @lgn21st 这样的话不会存在安全问题么

#31 楼 @jialezhang 用 passenger 安装应该还算容易,安装中尽量少用 sudo 你在这里先直接建这个目录,再给权限 sudo chown username /opt/nginx。安装时这问题就解决了 这里有一篇过时的,仅供参考

#38 楼 @leekelby 已经哭了,权限的什么的全部都给了,nginx 所在目录,rails 项目所在目录全部给的是 Username ,执行后,还是 forbidden,/opt/nginx,参考你给的文章安装还是 forbidden

#36 楼 @lgn21st 在/home/jialezhang/dev/nginx 下面装了,查看权限全部都是 jialezhang,涉及到的文件都属于可读可写可操作的目录,在.opt/nginx 下面安装了,/opt 的用户也改成了 jialezhang,nginx.conf 里面加了 User:jialezhang,还是 forbidden,日志说的还是Index of "PATH/TO/MYAPP/public is forbidden",是不是要在项目文件的 config 里面修改什么

some.rbin `initialize': can't convert nil into String (TypeError)

亲,上面大大的写着 不能将 Nil 转化成 String

也就是说:思路要跟着 Nil 走,什么东西在转成 string,又是什么东西是 Nil.亲,这样问题就解决了。

这个练习程序的本意是读取一个外部文件,因此首先要在程序文件之外,另建一个文件, 为了简单起见,在程序文件的同级目录下新建一个文本文件,内容随便,命名为 test.txt 然后在命令行里面运行你这段程序: ruby some.rb test.txt 是不是可以了?

some.rb 是这段程序的文件名,test.txt 是要读取的文件名,这里作为 some.rb 的参数传入程序, 程序中这一句: filename = ARGV.first 就是来接收参数的,其中 ARGV 是参数集合,你简单把它理解成数组,.first 表示取第一个元素,也可以用下面写法替换: filename = ARGV[0]

需要 登录 后方可回复, 如果你还没有账号请 注册新账号