トップページ⇒tech
983コメント375KB

Ruby 初心者スレッド Part 41

■ このスレッドは過去ログ倉庫に格納されています
0001京 ◆SsSSsSsSSs 2011/02/10(木) 13:47:51
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。

★注意★ Ruby 1.9.2 は初心者には若干時期早尚です。初心者には Ruby 1.8.7 を強くお勧めします。
 文字エンコーディング等の外部基礎知識が必要な上、不完全対応の第三者ライブラリでの問題の切り分けが手間です。
 迷う点の少ない1.8.7に習熟→おもむろに1.9.2の変更点のみ重点学習、とすればスムーズに移行できるでしょう。

関連スレやURLは>>2-5あたりを見てください。Ruby on Rails の質問は Webプログラミング板の Rails スレへ。

■質問する人へ
質問する前に次の3つをすること。ここで回答を待つよりそのほうが早い。
 ・エラーメッセージの共通そうな部分やエラーの出るモジュール名でググる
 ・マニュアルで引っかかったクラスの記述を探す http://www.ruby-lang.org/ja/man/
 ・FAQを一応読む http://www.ruby-lang.org/ja/man/?cmd=view;name=Ruby+FAQ
質問には以下を書くこと。へたくそな質問は再提出を要求される。
 ・最終的にやりたいこと(もっとよい方法がある場合が多いので)
 ・エラーメッセージ(自力で訳さずなるべくそのままで)
 ・詳しい内容(「動きません」「うまくできません」では回答しようがない)
 ・実行環境(OS名、Rubyのバージョン(ruby -v でわかる))
回答してくれた人には「ありがとう」のひとことをいってあげて。

■回答する人へ
相手は初心者、根気よく育てるつもりで。質問がへたくそなのも大目にみてあげる。
それができないならこないこと(だって初心者スレだもん)。
 ・既出な質問やFAQは「XXXを読め」でいいので、叩かない&怖がらせない。
 ・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
 ・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0552デフォルトの名無しさん2011/03/25(金) 14:49:21.63
line なんだからそりゃ改行つきだろう
行改の直後から行改の直後までが「行」だ

ただ、この正確な動作はあまり直感的ではなく文句がつきまくったので
String#lines という改行抜きで配列にするメソッドが 1.9 と 1.8.7 についた
0553デフォルトの名無しさん2011/03/25(金) 15:11:35.16
チョップすればいんじゃね
0554デフォルトの名無しさん2011/03/25(金) 15:41:59.47
RUBY_DESCRIPTION=> "ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin9]"

# String#lines で Enumerator が返る。
File.read('/etc/passwd').lines.class
=> Enumerable::Enumerator

# Enumerator なのでそのままいろいろ出来る。
File.read('/etc/passwd').lines.grep(/root/).first
=> "root:*:0:0:System Administrator:/var/root:/bin/sah\n"

# 配列でないと出来ないことをやりたい場合は to_a すべし。
irb(main):003:0> File.read('/etc/passwd').lines.shuffle
NoMethodError: undefined method `shuffle'
irb(main):004:0> File.read('/etc/passwd').lines.to_a.shuffle
=> (略)

尚、各行は改行そのまま。不要なら map(&:chomp) する。
0555デフォルトの名無しさん2011/03/25(金) 18:44:23.72
> String#lines という改行抜きで配列にするメソッドが 1.9 と 1.8.7 についた
俺の1.9.2には付いてないみたいだ
0556デフォルトの名無しさん2011/03/26(土) 22:23:11.97
ありがとうございます
そういうものなのですね
chompするなりすることにします
0557デフォルトの名無しさん2011/03/27(日) 10:30:33.33
Loggerってスレッドセーフですか?
0558デフォルトの名無しさん2011/03/27(日) 10:37:04.69
write時に@mutex.synchronizeしてるからスレッドセーフなんじゃね?
0559デフォルトの名無しさん2011/03/27(日) 11:24:54.32
おお、ほんとだ。助かった。
0560デフォルトの名無しさん2011/03/27(日) 11:42:30.35
rubyフォージ?(スペル忘れた)いいですね
常に最新版が提供されてていいですね
公式サイトで紹介されてる国内の配布サイトのは古いのばっかりでやる気を感じられない
0561デフォルトの名無しさん2011/03/27(日) 11:57:29.59
表示系ライブラリはスレッドセーフとか考えないと駄目なのかなあ
めんどくさいなあ
0562デフォルトの名無しさん2011/03/27(日) 12:09:32.53
自作ライブラリがスレッド上で動作する可能性を織り込んで対策するようになれば初級脱出
0563デフォルトの名無しさん2011/03/27(日) 12:22:56.92
Rubyのスレッドはよーく考えてセッティングしないと逆に遅くなるので嫌い
0564デフォルトの名無しさん2011/03/28(月) 21:25:58.93
>>560
何の最新版かしらんが
rubyフォージよりも最新版を見たければrubygems.orgやgithub見ておけばいいんでないの
0565デフォルトの名無しさん2011/03/28(月) 22:05:35.57
>>564
単にRAAが打ち捨てられただけなのでは?
0566デフォルトの名無しさん2011/03/29(火) 17:31:27.83
すみません余所にも書いたのですが返事がなかったためここでも質問させていただきます。

RubyをEmacsで使おうとして苦戦しております。

http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=Emacs

このサイトにて、
「Debianの"ruby-elisp.deb"のようにパッケージが利用できるなら、
それをインストールする。ソースからビルドした場合などは、
適当な場所(たとえば~/site-lispなど)にmisc/*.elをコピーする。
そして~/.emacsに次のように書いておく」
と書いてあります。

最後の部分は恐らくパスを追加するということなのだと思うのですが、
私はパスを追加するとはコントロールパネルから辿って行って、絶対パスを
ペーストするやり方しか知らないので、ここがよくわかりません。

~/.emacsって言うのはどこを指していて、どうやって書き込めばいいのでしょうか?
0567デフォルトの名無しさん2011/03/29(火) 17:36:41.38
そのチルダはホームディレクトリのことだけど
EmacsやるまえにLinux入門みたいなの一冊買ったほうがいいよ
0568デフォルトの名無しさん2011/03/29(火) 17:37:44.10
Emacsを勉強するかRubyを勉強するかどっちか片方だけにしておけ
Emacsの知識がないならRubyに慣れるまではとりあえずふつうのエディタ使え
0569デフォルトの名無しさん2011/03/29(火) 17:39:27.26
~ってのはホームディレクトリ。
ababaさんがログインしたらだいたい、
/home/ababa
それか
env | grep HOME=
としてみてもわかる。
そこに、,emacsっていう名前のファイルがあればそれを編集。
0570デフォルトの名無しさん2011/03/29(火) 18:43:25.24
Windowsの予感!
0571デフォルトの名無しさん2011/03/29(火) 18:49:11.05
…ぬ、ぬう……

Windows版Emacs(というかXEmacs)にはイヤな思い出しかないんだが
とりあえず、そのサイトはWindowsを対象にしてないのは確かだ
05725662011/03/29(火) 19:33:14.48
みなさんご親切にありがとうございました。
なんとかやってみます。
05735662011/03/29(火) 19:34:06.79
あ、windowsでやってます。
使いにくいのでcygwin使ってるんですが、ちょっと仕様が違ったりするんですかね??
0574デフォルトの名無しさん2011/03/29(火) 20:18:34.29
日本でサマータイムが導入されたらどう対応したらいいんですか?
0575デフォルトの名無しさん2011/03/29(火) 20:49:46.05
>>573
仕様っつーか、ちょっとしたトラブルとかのときに
Cygwinの問題なのかWindowsの問題なのかソフトの問題なのかよーわからんことになる。
05765662011/03/29(火) 20:54:38.03
>>575
(´・ω・`)え。。

(´・ω・,';,';,',

(´・ω,';,';,',

(´・ω・,';,';,',

(`・ω・´)仕方ないのでこのままがんばってみます!
meadowってやつで頑張ってみます!ありがとうございました!
0577デフォルトの名無しさん2011/03/30(水) 00:04:56.49
普通のテキストエディタでいいじゃない
0578デフォルトの名無しさん2011/03/30(水) 01:20:36.88
ノーパソ使ってるとemacsのほうが結局使いやすいかも。
導入時に多少てこずったとしても。
0579デフォルトの名無しさん2011/03/30(水) 10:30:04.55
Rubyの導入したくご教示お願いします
Windowsを利用してます
Apache2.2も入れてます
主に日々の作業を自動化する目的で利用するのとCGIの勉強用途に利用します

http://rubyinstaller.org/downloads/からRuby 1.8.7-p334をダウンロードしてインストールしました
gem update --systemでgemは1.6.2にアップデートできました
ほかに何かインストールや設定するものはございますでしょうか?

RedmineとRuby on railsも入れてみたいなと思うのですが
ApacheのドキュメントルートがC:\www\docroot\で
ユーザーディレクトリがC:\user\*\public_htmlとなっております(*の部分は適当に付けたユーザー名が入ります)
gemでインストールする場合はユーザーディレクトリに入れて動かしたいのですがディレクトリの指定は可能でしょうか?
0580デフォルトの名無しさん2011/03/30(水) 11:00:35.17
Rails使う場合は全部をRails風にしたほうがいいと思う
RailsとCGIはあんまり相容れないから
Railsのお話はこちら
ttp://hibari.2ch.net/test/read.cgi/php/1292032736/

Apache さんが使う gem は Apache さん用にインストールするか
gem をシステムワイドにインストールして Apache さんに使わせるかだと思う

gem はユーザーのホームに .gemrc があればそれを読むので
そこに gem: "--user-install" とでも書いとけ
0581デフォルトの名無しさん2011/03/30(水) 11:14:10.38
前スレ1〜10ぐらい昔にputで文字列を出力するのがイヤで引退した者です
昔からprintとpってありました?
put、print、pの違いが分かりません
0582デフォルトの名無しさん2011/03/30(水) 11:18:04.34
コマンドラインからruby -Ks test.rbとして呼び出すのを
この-Ksをファイルの中に書いてruby test.rbで呼ぶ方法を教えてください
0583デフォルトの名無しさん2011/03/30(水) 11:35:03.01
>>37-38
ありがとうございます
0584デフォルトの名無しさん2011/03/30(水) 12:34:04.19
>>581
>>11

>>582
スクリプトの1行目に適当に

#!ruby -Ks

と書いておくというのはどう
あらゆる環境で動作するかどうかは保証できないけど

$KCODE を使う場合は

$KCODE = "s"
load "./test.rb"

と書いた main.rb を ruby main.rb で呼ぶとかそういう小細工が必要
0585デフォルトの名無しさん2011/03/30(水) 12:37:52.82
winならバッチにするとか

ruby -Ks -x "%~0"
goto :eof

#!ruby
0586デフォルトの名無しさん2011/03/30(水) 12:41:40.87
for i in 1..10
print rand(3)+1, "\n"
end

どうもRubyの乱数生成は偏りがある感じがあるのですが
良い乱数生成方法はございますか?
0587デフォルトの名無しさん2011/03/30(水) 12:55:20.16
>>586
その結果を見てわかるようなレベルの偏りは存在しない
0588デフォルトの名無しさん2011/03/30(水) 13:06:41.71
>>586
Rubyの乱数はMTだからそんなに粗悪な値は出ないはずだけど

常に偏らない値が欲しいならこんなんにするしかない
乱数生成とは又違う話だけど
[1,1,1,2,2,2,3,3,3,rand(3)+1].shuffle
0589デフォルトの名無しさん2011/03/30(水) 13:18:07.66
確かに、サイコロ5回振って1が3回出ても怒らないのに
1から6までの乱数を返すルーチンで1が3回返ったら怒る人は稀にいる
乱数による各々の出目は平均的でなければならないんだってさ
0590デフォルトの名無しさん2011/03/30(水) 13:25:18.42
いまさらながら、確率ってなんか不思議だな。
サイコロ振りまくったら、出目ごとの出た回数が平均的になっていくなんて。
0591デフォルトの名無しさん2011/03/30(水) 13:37:28.98
スゴロクで1が連続で出ると萎えるじゃん
0592デフォルトの名無しさん2011/03/30(水) 14:20:03.56
複数回の試行を1事象としてみたとき、
偏って同じ目が出るという事象も
平均して出るという事象も
ぜんぜん出ないという事象も
生じる。
0593デフォルトの名無しさん2011/03/30(水) 18:07:33.88
Ruby 1.8.7 です。
以下のようなフォームでメールアドレスを入力し「次へ進む」を押すと、
登録完了メールがユーザに届くプログラムを作成中です。

<form method='post' action='test.rb'>
<input type='text' name='email'>
<input type='submit' value='次へ進む'>
</form>

メールを送る機能は既に完成し、メールの送信自体は行えているのですが
上記のフォームを実際に使用してみると Internal Server Error と表示されてしまいます。
また、エラーが発生するにも関わらずメールは意図したとおりのアドレスに送信されます。
作成して利用しているスクリプトの概要は以下のとおりです。

mail = TMail::Mail.new
mail.to = '[email protected]'
mail.from = '[email protected]'
mail.subject = '登録完了'.tojis
mail.date = Time.now
mail.mime_version = '1.0'
mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'}
mail.body = ('登録完了いたしました').tojis

Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.sendmail(mail.encoded, mail.from, mail.to)
}

何が原因なのでしょうか?なにかおわかりになる方がいらっしゃれば、助言お願い致します。
0594デフォルトの名無しさん2011/03/30(水) 18:16:37.50
他のやり方でやってみたら?
俺昔どうやってたかな?と調べたら以下のようにやってた。
kconv使うかどうかはさておき、他のパラメータの与え方はこんなもん。
これで十分?

mailbody = Kconv.tojis(mailbody)
Net::SMTP.start(smtphost, smtpport) {|smtp|
src = <<EndOfMail
From: #{mailfromaddr}
To: #{mailtoaddr}
Subject: #{subject}
Content-Transfer-Encoding: 7bit
Content-Type: Text/Plain; charset=iso-2022-jp

#{mailbody}
EndOfMail
smtp.send_mail src, mailfromaddr, mailtoaddr
}
0595Perl忍者 ◆M5ZWRnXOj6 2011/03/30(水) 18:18:56.42
お前がバカだからだよ原因は
0596デフォルトの名無しさん2011/03/30(水) 18:24:59.21
>>593
HTTPレスポンスとしてはどういうものを返しているの?
ちゃんと200が返るようになってるの?
0597デフォルトの名無しさん2011/03/30(水) 18:34:44.13
>>594
確か自分も以前そのやり方でやろうとしていたんですが、
そのやり方でのユーザ名とパスワードの設定方法が
わかんなくて今のやり方に行き着いたような気がします。
でも、他のやり方を探してみるのはありですね。
ちょっとやってみます。ありがとうございます。

>>596
ありがとうございます。
正しいやり方なのかどうかはわからないのですが、
先ほどのスクリプトの末尾に

print "Content-Type: text/html\n\n"
print "OK"

のようにやってみたりはしました。
我流?というか常識的なところを理解してません、
正しいやり方を教えていただけるとありがたいです。
0598デフォルトの名無しさん2011/03/30(水) 19:26:05.15
>>593
>上記のフォームを実際に使用してみると Internal Server Error と表示されてしまいます。
うん、

……ってそれで終わりかよ!
Internal Server Error ってことは Apache のログにエラーの出力があるだろそれ読めよ!
0599デフォルトの名無しさん2011/03/30(水) 19:40:55.23
思いっきり補完すると
「ローカルで問題なく動作するスクリプトをサーバに設置するとなぜか動作しません」
なわけで、そりゃサーバ側の環境が悪いんじゃないん、というお話に

HTTP サーバのエラーログあたりに原因究明の鍵というかそのまま答が表示されてるはずなんだけど
たぶんそれを読む権限がなく、HTTP サーバがどうやって Ruby を実行してるか調べることもできないと推測
おまけにそれの原因は >>593 に書いたスクリプト以外の部分にあると

$SAFE=1 と先頭に書いた上でローカルでスクリプト実行してたらなにか warning が出るかも
CGI がファイル作成できるのなら、$stderr を捻じ曲げてファイル出力にしてサーバ実行するとなにか書いてあるかも
$stderr = File.open('error.txt') と先頭に書いて error.txt を実行後に読んでみるとか
0600デフォルトの名無しさん2011/03/30(水) 19:43:24.33
× $stderr = File.open('error.txt')
○ $stderr = File.open('error.txt', 'w')
0601デフォルトの名無しさん2011/03/30(水) 20:08:26.76
>>595
消えろカス
0602デフォルトの名無しさん2011/03/30(水) 20:13:13.99
>>601
今のところレスしたのお前だけだぞ
0603デフォルトの名無しさん2011/03/31(木) 09:58:02.54
>>598 >>599 >>600
ありがとうございます!
ご教授いただいたとおりにやってみましたので報告致します。

まずは Apache のエラーログを見てみました。
が、以下のように表示されているだけでした。
Premature end of script headers:test.rb, referer: http://foo/bar.html
とりあえずここに有益な情報はないと判断しました。

つぎに「HTTP サーバがどうやって Ruby を実行してるか調べることもできない」という部分ですが、
具体的に何をどうすればよいのかがわからなかったので保留させていただきました。

つぎに「先頭に」$SAFE=1 と $stderr = File.open('error.txt', 'w') を書き足した上で、
ローカルでスクリプトを実行してみました。
この「先頭に」の位置ですが、

#!/Ruby/bin/ruby.exe
# -*- coding: utf-8 -*-.
(ここ)
require "rubygems"
require "cgi"
require "tmail"
require "net/smtp"
と判断しました。
0604デフォルトの名無しさん2011/03/31(木) 10:03:35.76
再度ローカルにてスクリプトを実行した結果、出力されたエラーは以下のとおりでした。

C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/defaults.rb:43:in `exist?': Insecure operation - exist? (SecurityError)
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/defaults.rb:43:in `default_path'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems.rb:726:in `path'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:57:in `installed_spec_directories'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:47:in `from_installed_gems'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems.rb:1025:in `source_index'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/gem_path_searcher.rb:135:in `init_gemspecs'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/gem_path_searcher.rb:14:in `initialize'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems.rb:984:in `new'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems.rb:984:in `searcher'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems.rb:206:in `try_activate'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:57:in `require'
from test.rb:9

ちなみに require 以下に $SAFE=1 と $stderr = File.open('error.txt', 'w') を書き足した場合は
特にエラーは出力されませんでした。
0605デフォルトの名無しさん2011/03/31(木) 10:26:10.68
一番肝心な「エラー出力先をファイルにした上でサーバで実行」がないぞ
ローカルで$SAFEを上げて実行してセキュリティエラーが出るのはそりゃ当たり前

というか、もしかして>>596の言うように HTTP としてのレスポンスが何もないだけなんじゃ…
CGI なんだから、リクエストに対して返すレスポンスのステータスが空文字列だとまずい
適当な「メール送信しましたありがとうございます」なHTMLを返すとかにしておけ
0606デフォルトの名無しさん2011/03/31(木) 10:31:16.38
こういうときのステータスって201?
0607デフォルトの名無しさん2011/03/31(木) 10:37:20.29
>>606
「○○さんありがとう! トップに戻る」というカスタムなHTMLを返したいなら200
ブラウザ真っ白の空っぽのボディでいいなら201か202
静的な「ご利用ありがとうございました.html」に飛ばすだけなら302
0608デフォルトの名無しさん2011/03/31(木) 11:01:13.61
>>605
申しわけありません、報告し忘れていました。
サーバ上で実行=ブラウザでアクセス と思ってよろしいでしょうか??
もしそうであればファイル error.txt に出力された内容は、上記のエラー内容と全く同じでした。

レスポンスに関してなのですが >>597 で書いたようにこのスクリプトの末尾に
print "Content-Type: text/html\n\n"
print "OK"
や
header = cgi.header({"charset"=>"Shift-JIS"})
puts header
puts <<-EOS
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=Shift-JIS'/>
<meta http-equiv='Content-Language' content='ja'/>
<title>test</title>
</head>
<body>
<p>OK</p>
</body>
</html>
などとやってはみているのですが、現状うまくいっておりません。
なにか間違っているのでしょうか??
0609デフォルトの名無しさん2011/03/31(木) 11:08:14.44
サーバ上で$SAFE=1にしても同じなのは当然だろ…
0610デフォルトの名無しさん2011/03/31(木) 11:24:53.15
わかってない人同士が混乱してるなw

CGI は HTTP レスポンスを「返さなければならない」
200 でいいから返しておけ
返し方わからないなら今日は作るの諦めろ

サーバの CGI が $SAFE=1 で実行されている場合、
PATH がワールドに対して読み書き可能になっていると、
require でセキュリティエラーが出ることがある
ttp://www.ruby-lang.org/ja/man/html/_A5BBA5ADA5E5A5EAA5C6A5A3A5E2A5C7A5EB.html
gem の変数が環境変数由来なので、たぶんここでもセキュリティエラーが出る可能性がある
warn $SAFE をどっかに書いてサーバで実行して値確かめて、0以外が表示されたら $SAFE が原因

スクリプトの本体は実行されてるそうなので、最終的な HTTP レスポンスをうまく返せてない説に一票
NPH で実行されてて、自前で HTTP ステータスを書き出さないといけないのだろう

print "HTTP/1.1 200 OK\r\n"
print "Content-Type: text/html\r\n\r\n"
print "<html>done.</html>"
0611デフォルトの名無しさん2011/03/31(木) 11:41:15.72
そもそもCGIでページを表示させるのはできてるの?

cgi = CGI.new
cgi.out({"type" => "text/html", "charset" => "shift_jis"}) {
<<END
あばば
END
}

メールと組み合わせず、まず表示だけやってみたら?
0612デフォルトの名無しさん2011/03/31(木) 12:09:20.80
>>611
ありがとうございます、表示はできています。
>>593 の
Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.sendmail(mail.encoded, mail.from, mail.to)
}
のところをコメントアウトして、代わりに >>611 のような適当な HTML を
表示させるような命令を書けば普通に表示されます。

なので >>610 の NPH で〜というのも恐らく違うのではないかと思います。
実際に「自前で HTTP ステータスを書き出す」というやつも試してみましたが、
うまくいきませんでしたし…。

>>610 さん、本当にありがとうございます。
先ほどからお話にあがっている $SAFE というものについて調べてみようと思います。
0613デフォルトの名無しさん2011/03/31(木) 12:19:12.13
Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
}

これだけにしてうまくいってる?startのパラメータは正しい?

> のところをコメントアウトして、代わりに >>611 のような適当な HTML を

そもそも、コメントアウトしたらまずいんじゃない?
なんらかの表示をさせてる?
なんらかの表示をさせなきゃ、
Premature end of script headers:test.rb,
って出るのも当然かも。
0614デフォルトの名無しさん2011/03/31(木) 12:45:45.41
>>613
>>611 で「メールと組み合わせず、まず表示だけやってみたら?」とのことだったので、
「表示だけなら出来てますよ」と回答したつもりだったのですが…。
もしずれたことを言っていたら申し訳無いです…。

Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
}
これだけにしてうまくいってる?startのパラメータは正しい?

というのは、
smtp.sendmail(mail.encoded, mail.from, mail.to)
を外したら表示がうまくいくかということでしょうか??
とりあえずやってみましたが表示はうまくいきません。

パラメータに関してですが、いちおうメールの送信は正常に出来てはいますので、
今のところは正しいのではないかと判断しています。
わたしの未熟さゆえ、アドバイスの意味が理解出来ていない可能性がありますが、
ありがとうございます。
0615デフォルトの名無しさん2011/03/31(木) 12:52:09.51
> パラメータに関してですが、いちおうメールの送信は正常に出来てはいますので、

なるほど。Net::SMTP.startのブロックは正しく動いてると。

> >>611 で「メールと組み合わせず、まず表示だけやってみたら?」とのことだったので、
> 「表示だけなら出来てますよ」と回答したつもりだったのですが…。

いえ、それについてはこちらが早とちりしたかも。うん、了解。テスト了解、その次の話。

一般的に、エラーメッセージを得たら、それをコピーしてそのままぐぐりって学ぶのが正解。
Premature end of script headersでぐぐったらいっぱい情報を得れると思う。

 メッセージの意味
 cgiプログラムがContent-Type ヘッダを出力する前に終了した

だから、メール送信をさせようとしたときも、なんらかの出力をして、
そのうえでスクリプトが終わるようにしないといけないんでは? という話。
0616デフォルトの名無しさん2011/03/31(木) 12:58:12.62
>>610
再度ご報告。
スクリプトのいろんな箇所に warn $SAFE と書いて
実行してみましたが error.txt に出力されたのは 0 のみでした。
(いちおう申告、先頭の $SAFE=1 はコメントアウトしました)

ありがとうございます。
0617デフォルトの名無しさん2011/03/31(木) 12:59:11.91
>>613の1段落目と2段落目は別の話だな
>>610にもあるが、CGI は HTTP のレスポンスを絶対に返さなければならない
「メール送るだけの CGI だからメールだけ送って終わり」ということはできない
Web ブラウザ経由で指示をしたなら、なんらかの返事をブラウザへ返さないと Web サーバはエラーとみなす

"Premature end of script headers" と Web サーバに記録されるエラーは典型的で、
・ Web ブラウザに返す返事の(HTTP 1.1/200 OK 等の)前に CGI がエラーや警告を出して混ざってわけわかめ
・ Web ブラウザに返す返事が、そもそも HTTP ステータスすら 1文字もない
のどちらかのときによく起こる
絶対に後者ではないという確証が得られてから、前者の CGI 本体のエラー潰しをする

HTTP 1.1/200 OK だの Content-Type: text/html だの、cgi.out だのの表示をしろというのは症状チェック用ではない
そもそもの CGI 動作に必須なものだ
0618デフォルトの名無しさん2011/03/31(木) 15:09:53.83
>>615 >>617
ありがとうございます。
誤解を与えてしまっていたようで申しわけありません。
たぶん私が「200 を返す」が何を指しているのか、
はっきり確信出来ていなかったのが原因なのではないかと思います。

テスト用などではなく、必須という認識は一応あるので、スクリプトの末尾には必ず
「HTTP 1.1/200 OK だの Content-Type: text/html だの、cgi.out だの」は表示しています。
わたしの最初の書き込みが >>593 なのですが、このソースの直後に

print "Content-Type: text/html\n\n"
print "<html>OK</html>"

のように必ず書いています。

現在の状況を私の見解でまとめてみます。
上記の「200 を返す」文を加えたソースを使用しても、
メールは飛ぶのですがブラウザには Internal Server Error と表示されます。
エラーの内容は Premature end of script headers です。
メールは飛ぶのでメールのところのプログラムは正常なのかな、と思いたいのですが
>>612 に書いたようにメールの部分3行をコメントアウトして実行すると、
当然メールは飛ばないのですがページ(<html>OK</html>)は表示されます。

メール部分は正常に動いているように思えるのに、疑わしいのもメール部分なのかな…
と、勝手に思っております。みなさま、どう思われるでしょうか?
0619デフォルトの名無しさん2011/03/31(木) 15:20:19.72
なるほど。メール部分三行を生かすと、ページは表示されないと?
メールを送ったあとにスクリプトが異常終了してるのかな?

begin
 メール部分三行
rescue => exc
 print "Content-Type: text/html\n\n"
 print "<html>#{exc}</html>"
end

みたいに一度してみたら?


0620デフォルトの名無しさん2011/03/31(木) 15:49:45.88
>>619
ありがとうございます。
試してみたのですが変わらず…です。
うーん…。
0621デフォルトの名無しさん2011/03/31(木) 16:21:02.69
>>619 で「メールを送ったあとにスクリプトが異常終了してるのかな?」と言われた件を検証してみました。
と言っても

begin
Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.send_mail(mail.encoded, mail.from, mail.to)
}
rescue => exc
print "Content-Type: text/html\n\n"
print "<html>#{exc}</html>"
end
print "Content-Type: text/html\n\n"
puts <<-EOS
<html>
<body>
<p>OK</p>
</body>
</html>
EOS


としただけなのですが。
結果、一度の実行で2通メールが送られてきました。
どういうことなのでしょうかw もう謎が深まるばかりです…。
0622デフォルトの名無しさん2011/03/31(木) 17:02:22.52
二通?? えーっw

print "Content-Type: text/html\n\n"
s = 'OK'
begin
Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.send_mail(mail.encoded, mail.from, mail.to)
}
rescue => exc
s = exc.inspect
ensure
puts <<-EOS
<html>
<body>
<p>OK</p>
</body>
</html>
EOS
end

みたいにしてContent-Typeを必ず出してみるとか。

0623デフォルトの名無しさん2011/03/31(木) 17:03:03.39
おっと。

<p>#{s}</p>

で。
0624デフォルトの名無しさん2011/03/31(木) 17:09:47.00
>>622
あ、すみません。

begin
 Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
  smtp.send_mail(mail.encoded, mail.from, mail.to)
 }
rescue => exc
 print "Content-Type: text/html\n\n"
 print "<html>#{exc}</html>"
end

Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
 smtp.send_mail(mail.encoded, mail.from, mail.to)
}

print "Content-Type: text/html\n\n"
puts <<-EOS
<html>
<body>
<p>OK</p>
</body>
</html>
EOS

の間違いでした。
もしメールを送信した直後に異常終了してるなら、
2回目の送信が行われるわけないと思ったわけです。
0625デフォルトの名無しさん2011/03/31(木) 17:17:34.61
>>622
うーん、試してみたがやはりだめです…。
なんども申し訳ない。ありがとうございます(涙)
0626デフォルトの名無しさん2011/03/31(木) 18:25:51.18
ところで
print "Content-Type: text/html\n\n"
って\nだけでいいの?
\r\n\r\nじゃないのかな

WindowsでRubyで遊んでるだけの私にはWebサーバーのことはよくわからんけど
OSとかWebサーバーが何なのかとか、手元にサーバーがあるのかとか
サーバーの環境をもっと詳しく書かないとアドバイスしにくいんじゃないのかな
0627デフォルトの名無しさん2011/03/31(木) 19:15:38.80
>>610,617
200 OKはWebサーバ側で勝手に付け加えてくれるよ
もしCGIスクリプト側でつけるのが必須なのであれば

print "Content-Type: text/html\n\n"
print "<p>hello, ruby cgi!</p>"

すら動かない

>>626
ApacheならLFしかなくてもCR LFに直してくれるよ
他も似たようなものじゃないか
0628デフォルトの名無しさん2011/03/31(木) 20:16:53.66
content-type出力の前後でerror.txtに何かメッセージを出力してみたら?
0629デフォルトの名無しさん2011/03/31(木) 20:31:18.82
ところで>>624を見る限り2通送られるのは正常じゃないか
メール送信処理がふたつ書いてあってどっちも実行されてるんだろうから

1通だけ送りたいのなら2番目のNet::SMTP...を削れば済むような
0630 忍法帖【Lv=5,xxxP】 2011/03/31(木) 20:35:18.06
というわけでこんな感じか

begin
 Net::SMTP.start(host, port, "localhost.localdomain", user, pass, "login"){|smtp|
  smtp.send_mail(mail.encoded, mail.from, mail.to)
 }
 print "Content-Type: text/html\n\n"
 print "<p>OK</p>"
rescue => exc
 print "Content-Type: text/html\n\n"
 print "<p>exception raised</p>"
end
0631デフォルトの名無しさん2011/03/31(木) 20:47:21.59
てゆーか、実行の余分なコストはゼロなんだろうし、
エラーが出なくなるまでスクリプトの内容削っていけばいいのに
もし10行くらいになってもエラーが消えなければ、個人情報がない範囲でスレに書け
0632デフォルトの名無しさん2011/03/31(木) 21:17:45.71
>>629
もしメールを送信した直後に異常終了してるなら、
2回目の送信が行われるわけないと思ったわけです。
0633デフォルトの名無しさん2011/03/31(木) 21:50:46.00
>>632
なるほど了解
ただ>>624だと一回目のメール送信直後に例外が発生した場合にややこしい

とりあえず確認すべきはprint "Content-Type: text/html\n\n"の前に
標準出力に何か出力していないかどうか。あとは>>631の言う通り
0634デフォルトの名無しさん2011/04/01(金) 09:52:59.91
            )
             (
         ,,        )      )
         ゙ミ;;;;;,_           (
          ミ;;;;;;;;、;:..,,.,,,,,
          i;i;i;i; '',',;^′..ヽ
          ゙ゞy、、;:..、)  }
           .¨.、,_,,、_,,r_,ノ′
         /;:;":;.:;";i; '',',;;;_~;;;′.ヽ
        ゙{y、、;:...:,:.:.、;:..:,:.:. ._  、}
        ".¨ー=v ''‐ .:v、,,、_,r_,ノ′
       /;i;i; '',',;;;_~⌒¨;;;;;;;;ヾ.ミ゙´゙^′..ヽ 
       ゙{y、、;:...:,:.:.、;、;:.:,:.:. ._  .、)  、}
       ".¨ー=v ''‐ .:v、冫_._ .、,_,,、_,,r_,ノ′
      /i;i; '',',;;;_~υ⌒¨;;;;;;;;ヾ.ミ゙´゙^′.ソ.ヽ
      ゙{y、、;:..ゞ.:,:.:.、;:.ミ.:,:.:. ._υ゚o,,'.、)  、}
      ヾ,,..;::;;;::,;,::;):;:;:; .:v、冫_._ .、,_,,、_,,r_,ノ′

0635デフォルトの名無しさん2011/04/01(金) 09:59:52.63
みなさんありがとうございます。

>>631 >>633
10行にはならなかったんですが、スクリプトの頭からお尻までが↓です

#!/Ruby/bin/ruby.exe
# -*- coding: utf-8 -*-.

require "rubygems"
require "cgi"
require "tmail"
require "net/smtp"

mail = TMail::Mail.new
mail.to = "[email protected]"
mail.from = "[email protected]"
mail.subject = "test title".tojis
mail.date = Time.now
mail.mime_version = "1.0"
mail.set_content_type "text", "plain", {"charset"=>"iso-2022-jp"}
mail.body = "test body".tojis

Net::SMTP.start("foo.bar.jp", 25, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.send_mail(mail.encoded, mail.from, mail.to)
}
print "Content-Type: text/html\n\n"
print "<html>OK</html>"
0636デフォルトの名無しさん2011/04/01(金) 10:05:53.04
>>626
ありがとうございます、たしかにそうかもしれません。
環境は

OS は Windows7 の 64bit
サーバーは Apache 2.2.16 (Win32)
Ruby のバージョンは 1.8.7

自分の PC に Apache インストールしていろいろやってるかんじです。
よろしくおねがいします。
0637デフォルトの名無しさん2011/04/01(金) 10:17:02.05
メールは tmail を使用する必要は必ずしもない
これだと rubygems と tmail が不要になる
cgi ライブラリも使用してないようなので外した
これで駄目な場合は…

#!/Ruby/bin/ruby.exe
# -*- coding: utf-8 -*-.
require "net/smtp"

from = "[email protected]"
to = "[email protected]"
mail_body = <<EOM
Date: Fri, 1 Apr 2011 10:03:27 +0900
From: #{from}
To: #{to}
Subject: test title
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-2022-jp

test body
EOM
Net::SMTP.start("foo.bar.jp", 25, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.send_mail(mail_body, from, to)
}
print "Content-Type: text/html\n\n"
print "<html>OK</html>"

というか外部にSMTP接続してるのね
Net::SMTP ってなにか警告出すことってあったっけ
0638デフォルトの名無しさん2011/04/01(金) 11:21:46.50
>>637
ありがとうございます。
試してみましたが、やはりうまくいきません。
今までと同じでメールは送信されるのですが、ページが表示されません。

プログラム云々ではなく、環境の問題なのでしょうか…?
0639デフォルトの名無しさん2011/04/01(金) 11:39:11.44
>cgi ライブラリも使用してないようなので外した
今回は頼ったほうがいいような気がする

ていうか
print "HTTP/1.1 200 OK\r\n"
は書いても害はないだろ
サーバ設定上不要だったら最初から全体がテキストとして余分に表示されるだけだ
そのとき改めて外せばいい
0640デフォルトの名無しさん2011/04/01(金) 11:46:02.15
>>635の最初と最後の二行ずつだけにしたスクリプトがエラーになるなら
ruby.exe の場所間違ってるか apache の設定じゃないかな
0641デフォルトの名無しさん2011/04/01(金) 12:38:18.11
>>640
>>612 に書いたようにメールの部分3行をコメントアウトして実行すると、
当然メールは飛ばないのですがページ(<html>OK</html>)は表示されます。
0642デフォルトの名無しさん2011/04/01(金) 12:45:46.89
>>635
メール送信を、表示のあとにもってきたら?
0643デフォルトの名無しさん2011/04/01(金) 13:04:28.21
>>641
CGIスクリプトとしてではなく単にコマンドラインから
C:\>ruby >>637のスクリプト.rb
とかしたらどうなるか試してみた?
0644デフォルトの名無しさん2011/04/01(金) 15:24:22.34
>>642
うーん、それでもだめでした…。
ありがとうございます。

>>643
はい、それだとエラーも出ずうまくいきます。
ありがとうございます。
0645デフォルトの名無しさん2011/04/01(金) 15:30:16.02
windowsです
gemでインストールしたライブラリってどこのフォルダにインストールされるのですか?
0646デフォルトの名無しさん2011/04/01(金) 16:39:50.13
>>645
ruby -rubygems -e "p Gem.dir" で表示されたディレクトリの中
cache/ と doc/ と gems/ と specifications/ の4つのディレクトリを(通常は)すべて使う
0647デフォルトの名無しさん2011/04/01(金) 16:40:58.07
>>646
ありがとうございます
確認dけいました
0648デフォルトの名無しさん2011/04/01(金) 17:08:18.64
おなかすいた

#!/Ruby/bin/ruby.exe
# -*- coding: utf-8 -*-.

from = "[email protected]"
to = "[email protected]"
mail_body = <<EOM
Date: Fri, 1 Apr 2011 10:03:27 +0900
From: #{from}
To: #{to}
Subject: test title
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-2022-jp

test body
EOM
@error = []
begin
require "net/smtp"
Net::SMTP.start("foo.bar.jp", 25, "localhost.localdomain", user, pass, "login"){|smtp|
smtp.send_mail(mail_body, from, to)
}
rescue Exception => ex
File.open('smp_error.txt', 'w'){|f| f.puts ex.backtrace }
@error << ex.backtrace
end
print "HTTP/1.1 200 OK\n"
print "Content-Type: text/plain\n\n"
puts @error
0649デフォルトの名無しさん2011/04/01(金) 17:13:33.58
>>644 です
問題がすべて解決したわけではないのですが、大きな進展がありましたのでご報告致します。

今まで Windows 7 上で Apache2.2.16 / Ruby 1.8.7 を動かして開発をしてきたのですが、
今回手元にあった Windows XP に Apache2.2.17 と Ruby 1.8.7 をインストールし、
問題のスクリプトを実行してみたところ、正常に HTML のページが表示されました。

何が原因なのかは依然わかりませんが、皆さまのご協力のおかげで解決に一歩近づけました。
ありがとうございます、心より感謝致しております。
0650デフォルトの名無しさん2011/04/01(金) 17:20:58.00
というかwindows用apacheって都市伝説かと思ってた。
実際に動かしている人がいるとは驚きだ。
0651デフォルトの名無しさん2011/04/01(金) 17:43:50.18
>>648
できるのであればなにかごちそうしたいです。
ありがとうございます。

実行してみたのですが 7 でも XP でも動作しませんでした。
ただし XP の方では

print "HTTP/1.1 200 OK\n"

この行を削除すると正常に動作し、ページも表示されました。
また、どちらの OS でも smp_error.txt というファイルは作成されませんでした。

>>650
Windows での情報が少ないな、とは思っていたのですがやはりそうなんですね。
ちょうどいろいろ不便で、限界を感じていたところだったので、
土日を利用して CentOS で環境を構築してみようかと思います。
0652デフォルトの名無しさん2011/04/01(金) 19:47:52.10
SMTP.startだけやってsmtp.send_mailしないとどうなる?
■ このスレッドは過去ログ倉庫に格納されています