Ruby 初心者スレッド Part 67
プログラミング言語 Rubyについての、初心者向けスレです。質問・要望・雑談などをどうぞ 質問するときは、OSやRubyのバージョン、エラーメッセージを書いて下さい。 Ruby on Rails については、WEBプログラミング板で 前スレ Ruby 初心者スレッド Part 66 https://mevius.5ch.net/test/read.cgi/tech/1578068134/ るりまサーチ (リファレンス検索) http://rurema.clear-code.com/ Rubyist Magazine - るびま http://jp.rubyist.net/magazine/ 逆引きRuby http://www.namaraii.com/rubytips/ Ruby コミュニティ公式 https://www.ruby-lang.org/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured paramsという名前のハッシュを関数の中で使う際、 :codeの組をhogeだけでなくmoge、kuge、sageなど 関数の引数で選べるようにする場合、 '+ 引数名 +'だとエラーになるようですが、 バリューに引数を使おうとしている事自体が根本的に間違っていますか? params = { :code=> 'hoge', ←'+ 引数名 +'だとダメ。ここを入れ替えたい :page => 1, :count => 5 } 意味が分からん。 エラーになるコードと希望する出力は何? >>152 APIを使用して住んでる地域の時間ごとの過去の天気を見る学習をするはずだったのですが 自分でも何がしたいのかわからなくなってきたのでちょっと出直します。 すみませんでした。 >>151 変数名と値(リテラル)の区別があやふやなんでは? 変数名をクォートしようとしている時点でヤバイ。 >>148-150 ありがとうございます。 rubyのインストールが上手く出来なかったので明日またやってみます。 >>150 Array#to_csvってかなり非効率的なんで避けたほうが無難 csv_str = CSV.generate{|csv| result_ary.each{|it| csv << it } } Pythonみたいに行けてるエクセルライブラリが欲しい。。 >>160 require "bundler/inline" gemfile do source "https://rubygems.org" ; gem "benchmark_driver" end Benchmark.driver do |x| x.prelude %{require "csv"} x.prelude %{ITEMS = Array.new(1000){ ["fooo", 12345,6789] }} x.report "to_csv", %{ csv_str = ITEMS.map{ _1.to_csv }.join } x.report "&:to_csv", %{ csv_str = ITEMS.map(&:to_csv).join } x.report "generate", %{ csv_str = CSV.generate{|csv| ITEMS.each{|it| csv << it } } } end 計測すると6倍ほどto_csvの方が遅い事がわかる to_csvは https://github.com/ruby/csv/blob/efb257e28f85741fb5c2637f707121e55e4c5ca9/lib/csv/core_ext/array.rb https://github.com/ruby/csv/blob/efb257e28f85741fb5c2637f707121e55e4c5ca9/lib/csv.rb#L1452 見ると分かるがCSV.new等を毎回行う手抜き実装(バグりにくいというメリットは確かにある) 1行だけならともかく複数行をcsv化したいなら微妙 実際にはどうせファイルに書き込むんだからファイルIOがボトルネックになるんで誤差だよ 無意味なベンチマークだね >>162 キャッシュなしフロッピーディスク💾を使ってるのかな?w >>162 Benchmark.driver do |x| x.prelude %{require "csv"} x.prelude %{require "tempfile"} x.prelude %{ITEMS = Array.new(1000){ ["fooo", 12345,6789] }} x.report "to_csv", %{ Tempfile.create{ _1.write ITEMS.map(&:to_csv).join } } x.report "generate", %{ Tempfile.create{ _1.write CSV.generate{|csv| ITEMS.each{|it| csv << it } } }} end 確かに縮まりはしたが うちのオンボロPCでも5倍弱の差が出ました。 c="C:\Program Files\7-Zip\7z.exe" p c で出力は > "C:Program Files\a-Zip\az.exe" となってしまうんですが、なんで7がaに変わってしまってるんでしょうか? 2.6.5p114 (2019-10-01 revision 67812) [x64-mingw32]です https://ja.wikipedia.org/wiki/ ベル文字 > ベル文字は、ASCIIとUnicodeでは十進数で7 > 1972年に作られたC言語では、ベル文字は文字定数 \aで表される。'a'は"alert"や"audible"の頭文字である。'b'は既にバックスペースに使われていた。 >>166 バックスラッシュ記法で8進数表記のパターンとして解釈されるから 式展開が必要なければシングルクウォートにするといい https://docs.ruby-lang.org/ja/3.0.0/doc/spec=2fliteral.html#backslash ¥007も¥07も¥7も同じ C言語由来のエスケープシーケンス >>166 >>168 のシングルクォートよりも、パスの区切り文字を「/」にすることをすすめたい。 パスの区切り文字が「¥」でなければいけないのはコマンドプロンプトなど一部のみ。 だいたいが「/」でも可。 >>167-169 まとレスにて失礼します aに置き換わる謎はわかりました シングルクォートなのですが、面倒くさいことにWindowsの決め打ちで空白が入っているので それを考えるとダブルクォートで囲まざるを得ず、けっきょくこんな形になってしまいました c="\"C:\\Program Files\\7-Zip\\7z.exe\"" このあと system("#{c} a -mx9 ...") みたいな形で呼び出します >>170 c = '"C:\Program Files\7-Zip\7z.exe"' >>171 ああなるほど それで行けますね 昔は自分でもそんな書き方してたかもしれなかったです >>172 ご案内ありがとうございます シングルクォートとダブルクォートの意味とか違いは理解していたのですが 中に\入れたときとか、とくに168さんに指摘されたように8進数での扱いが特別だということは よく理解していなかったので、これを機会に知識を正確にしておきます 完全にプログラミング0からで「スラスラ読めるrubyふりがなプログラミング」を買って始めたのですが macbookairでrbenvでruby3.0.1をダウンロードしてrbenv versionでは3.0.1と表示されるのですがruby -vでは2.6.3と元々入ってるrubyが表示されます まだ何も分かってないのにhomebrewとrbenvのダウンロードが上手くいかず色々見ながらやってきたので余計な事をしてしまったのではないかと心配です >>174 ですが 自己解決しました bash profileに何か誤ったものを書き込んでしまったようで消したら3.0.1に切り替わりました Rubyで、syntax error 的なものが生じていても、そのまま実行が続けられている ように見える現象が時々起きる。 これは何が起きている? errorが起きた場所で停止させる方法はある? >>176 そのエラーが起こった時に何が表示されているの? >>178 例えば、xxx という変数を定義してない状態で、 [aaa.rb] def some_func() ・・・ print( "xxx=#{xxx}\n" ); ・・・ end という関数を呼び出すと、 aaa.rb:3882:in `some_func': undefined local variable or method `xxx' for main:Object (NameError) from aaa.rb:5638:in `main' from aaa.rb:5667:in `<main>' と出るが、そのまま実行が続けられてしまう。 >>179 begin rescue end の構造してるだけじゃないの >>181 再現するコードを共有することはできますか? >>182 できない。 大事なコードだから非公開。 そうであれば我々にはわかりえない。 まあどっかでrequireをオーバーライドしてるとかじゃないの。 >>184 全部自分で書いたコードで、Rubyの基本的な機能しか使ってない。 また、検索してみたが、begin や rescue というキーワードは全く使ってなかった。 別スレッドも停止させたいのであれば、Thread.abort_on_exception=trueが必要とか? さすがのRubyでも、そんなアホみたいな「バグ」なんかないやろ。w おまえさん一人だけの症状なんだし再現できるコード・環境を出せない以上おま環 >>170 コマンドプロンプトでも普通に、/ を使える。 これで実行できる ruby C:/Users/Owner/Documents/a.rb パスに空白が入っている場合は、シングル・ダブルクォーテーションで囲む PowerShell(PS)でも良いし。 Windows Terminal なら、Bash, PS、コマンドプロンプトの3つを使える Powershellで標準出力をリダイレクトしてると Ctrl-C押した時at_exitに飛ばずに死ぬの何なの? そのアプリが、SIG-INT・中断をキャッチしない場合は、 SIG-KILL・強制終了されるのだろう 強制終了は、受け身が取れない。 たぶん、デフォルトの挙動は、そうなのだろう リダイレクトしていなければ普通にat_exitに飛ぶんだよ 試しにpythonでもatexit使ってみたが同様に強制終了される Traceback出力されるのにatexitは実行されない powershellがバグってる cmd /c 経由なら正常にリダイレクトおよびctrl+cできたわ え〜〜マジっすか 検証してくれてありがとうございました。 まずパイプが終了して、それに巻き込まれてpythonのプロセスが落ちるとかなんとか rubyの挙動を調べるためにpythonでググるってなんだかな 現在ラズパイにrubyとpythonを入れて処理を並列に自動実行しようと思ってます ただ台数が多いため一台ごとにソースを変えるのは回避したいです なので理想は起動時に最新のソースに自動で更新です このようなことをしたいときはどのようにするのが一番簡単でしょうか? rubyでサーバーから最新のソースをコピーしたあとにrubyとpythonを実行? 家で使用するのでセキュリティーとかは気にしません >>204 厳密に一斉に切り替わらなくてもいいならcronとかで定期的にGitHubからpullする 手段が目的だと堂々と言えるならKubernetesのクラスタ組むとかも面白い ライブラリのopenのように、 open() do |f| ・・・ end と書いてもよく、 f= open() ・・・ f.close と書いてもいいというクラスor メソッドは どうやって作ればいいのでしょうか。 yieldを使うとイテレータのみになってしまうし、 returnすると下の例だけになってしまいます。 >>208 ありがとうございます。 うまく作れました。 すみません、もう一つ教えて下さい。 rubyというかプログラムを書くとき全般の注意として、 ファイルopenとcloseはなるべく近くに書くようにと ありました。 恐らくclose漏れを警戒しているのだと思います。 yieldを使えば、以下コードでそれを実現できます。 def fileInterface f= open() begin yield f ensure f.close end end yieldを使わないパターンでは、 closeを近くにかけないのですが解決策あるでしょうか。 def open @f= open() return @f end def close @f.close end openメソッド実行 ・・・ ・・・(大量の処理) closeメソッド実行 >>210 大量の処理を関数にして分離。 あるいは、しょせん理想でしかないので、離れていても気にしない。 >>210 close漏れを警戒するのであれば、openにそのままブロックを渡した方がいい openはブロックの実行結果を返し、ブロック脱出時に勝手にcloseします まぁ、どうせclose漏れしてもそのうちGCに回収されるかプロセス終了時にcloseされる >>210 yield使った実装とやることは同じ f= open file begin 大量の処理を含むメソッド f # <― yieldがメソッドに変わるだけ ensure f.close end 同じだからこそ毎回同じことを書かなくてもいいようblock付きで呼び出す open(file){|f| 大量の処理を含むメソッド f} 大量の処理を手続きオブジェクトに分離するのは、やりました。 やっぱりそれしかないかな。 ブロック付きで渡すのはオブジェクト指向ではない コードになりやすく、今回は考えてないです。 また、全体をensureで囲うのは、 さすがにensure対象が暗黙的すぎてちょっとな・・・です。 >>214 > ブロック付きで渡すのはオブジェクト指向ではない > コードになりやすく そうか? まあ、「オブジェクト指向」にもいろいろあるからな。w railsにおいて あるフォームから特定の変数に送られるデータの内容を固定したいのですがなにかいい方法ありますか? 具体的には <%= form_with model: @hoge do |form|%> <%= form.text_field :name , value: 'hoge'%> <%= form.submit %> <% end %> と書かれている場合 hogeというモデルのnameという変数に必ずhogeが入るようにしたいのですが上の書き方だと初期値にhogeが入るだけで編集可能になってしまいます。 openに、ブロックを渡す方法は、 コンテキスト・マネージャーという、多くの言語で使われているデザインパターン これよりも良いものは作れないから、皆が使っている そりゃ、フォームはサーバーへ送られて更新されるものだから、 変更可能のフィールドが普通 変更不可のフィールドにするなら、 そのフィールドをサーバーへ送らないようにしないといけない そういうオプションがあるのかな? 「html disabled readonly」で検索! HTML の <input> 要素には disabled と readonly 属性が存在します disabled : コントロールが無効化され、フォームを Submit しても、値の送信が行われない readonly : 値の変更は行えないが、コントロールは有効なので、 フォームを Submit すれば値の送信が行われる 変更不可のフィールドなら、 <input> 要素などを使わずに、単にテキストを表示すれば? >>216 hidden_field使ってもいいけど そもそもformによる入力=webからの入力は信頼してはいけない >>222 直にソースで書くしか! ちなみに、XSRFも調べとくとええんちゃう? マスアサインメント脆弱性を、strong parameters で防ぐ。 更新できる列を、permit で限定する。 これは、コントローラーでの制限 params.require(:person).permit(:name, :age) Action Controller の概要 https://railsguides.jp/action_controller_overview.html モデルでのバリデは、 Active Record バリデーション https://railsguides.jp/active_record_validations.html Rails ガイド・Rails チュートリアル・黒田努の本などを読むか、 YouTube で有名な、雑食系エンジニア・KENTA のサロンへ入ると良い。 日本6位の、2千人入っている、虎の穴 >>217 ブロックで書くとテストコードが書きづらくないですか? 最近はテストコードのことを考えて、普通に、 file = open(file,'r') とか書いてます。 あと、ブロックはネストするからなあ。 >>222 何がしたいのか次第 'hoge'で固定するのであればformで入力させる必要はないですし なんらかの方法で生成するのであれば生成するタイミングを考えます 入力フォーム表示前に生成し固定する必要があるのであれば ActiveSupport::MessageVerifier ActiveSupport::MessageEncrypter session などを使う Rails の便乗質問するけど、 ユーザーの入力値により、条件判断して、 条件1 の場合には、列A だけを更新して、 条件2 の場合には、列B だけを更新する と言うのは、どのように書くの? モデルのcallback かな? ruby silver試験は公式問題集をやれば 合格できますでしょうか、学習時間も参考にさせていただきたいです。 silverを考えています。 バージョンがかなり古いとは思いますが、今のrubyとそんなに変わらないと思ってて大丈夫でしょうか Ruby の資格は、漏れも取っていない。 下のマネーフォワードの本で、良いと思う 改訂2版 Ruby逆引きハンドブック、2018 >>227 自己回答 ユーザーの入力値により、条件判断してはいないけど、 改訂4版 基礎 Ruby on Rails、黒田努・佐藤和人、2018 の400 ページで、 アクションのcreate/update で、 コントローラーのstrong parameters を変える例が書いてある 例えば、下のような感じ params.require(:person).permit(:name) params.require(:person).permit(:age) >>231 別に構わんが環境次第でUnpermittedParameters例外出そうな気がするので @person.update(xxx_params.except(:age)) 的な感じのほうがよいかも pythonなみの公式チュートリアルがあればいいのに Railsでも何でもいいんですが、ecサイトの様なユーザー登録とログインシステム をRubyを使って簡単に構築するライブラリの使い方が書かれている良い本は 有りませんか? >>234 Ruby on Railsのチュートリアル でいいのでは? 簡単に済ませたいならば、 Shopifyとか外部決済システムに外注すれば? スクレイピングしたいんですけど何を勉強すればいいですか 不正アクセスに問われたりしないでしょうか? セキュリティ対策はどのようなことに注意すればよいでしょうか? >>236 踏み台を準備してそこ経由でスクレイピングする >>236 とりあえず、関心のあるページをローカルに保存してnokogiriでアクセスしてみれば? crawler部分とscrap部分を分けるのが吉。 つまり、100pagesをスクレーピングするなら、まずhtmlをblob型でDBにinsertしてから欲しいデータをnokogiriで取り出すのだ。 >>234 よく見るのは、devise gem を使う パーフェクト Ruby on Rails、2020/7 には、載っていない 改訂4版 基礎 Ruby on Rails、黒田努・佐藤和人、2018/9 には少しだけ載っている。 ただし、この本は、Ruby 2.5.1, Rails 5.2 Ruby on Rails 6 実践ガイド、黒田努、2019/12、には載っている ただし、上の黒田努の2冊の本では、devise を使わず、自作している Rails チュートリアル・Rails ガイドも参照 YouTube で有名な、雑食系エンジニア・KENTA のサロンでは、 2千人の未経験者が、Rails の転職用ポートフォリオを作っている。 そこへ入って、聞いた方がよい >>236 サイトのrobots.txt を遵守すること! これを守らないと、営業妨害で逮捕される CSS Selector を勉強する。XPath は勉強しなくてよい。 JavaScript も、jQuery 程度は出来た方がよい gem は、Nokogiri, Selenium Webdriver Udemy の山浦清透、2021/6 【作業工程フル公開】エンジニアが30万円案件の制作過程を公開 www.youtube.com/watch?v=tYbVl6N8oxI PHP のLaravel で、マイナビ転職をスクレイピングして、データベースへ保存する 基本、この動画と同じ。 これを、Ruby on Rails へ置き換えるだけ >>234 Ruby on Rails, devise の動画 Farstep、2019/9 【Rails】deviseを使ったログイン機能の実装(名前でログインする方法を解説) www.youtube.com/watch?v=Lmq_WLkxp9c YouTube で「ruby on rails devise」で検索すれば、日本人の動画も多い Farstep, うるぞー、もぐらストア、 やんばるCODE 守護神・バグ取り名人 たけ >>242 >>サイトのrobots.txt を遵守すること! >>これを守らないと、営業妨害で逮捕される どういうことですか? 詳しくお願いします >>231 パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series)、2020/7 の92 ページで、 コントローラー内で、private メソッドを定義して、 条件によって、strong parameters を変える例が書いてある 管理者・一般ユーザーで変える例 params.require(:user).permit(:name, :admin) params.require(:user).permit(:name) >>247 >>242 に書いてある、山浦清透の動画を見れば分かる 各サイトには、robots.txt が置いてあって、 スクレイピングする場合は、必ず30秒空けるとか、 このフォルダはスクレイピングしてはならないとか、多くの条件が書いてある それを守っていないと、営業妨害になる スクレイピングは初心者向きじゃないので、各サイトと契約して、API を使うべき! なぜかと言うと、初心者のプログラムにはバグが多いから、 無限ループしたりして、サイトへ無限にアクセスしたりする それで、営業妨害で逮捕されるかも知れないから、すごく危険! プロでも、スクレイピングはしない。 必ず、サイトと契約して、APIを使う 5ch もそう。契約して、APIを使えと言ってる。 勝手にスクレイピングすると、訴えてくるかも知れない >>249 私のスクレイピングしたいサイトにはAPIは公開されていません またrobots.txtも設置されていません robots.txtでリクエスト間隔の指定なんてあるのですか? 常識的に数十秒から数分に一回程度のリクエストなら問題ないと思いますが 営業妨害ってどういう意味ですか IT企業に勤める知り合いはスクレイピングで求人を出すことがあると言ってましたが嘘でしょうか? 5chでスクレイピングしたら相手にバレて訴えられることがあるのですか? read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる