fc2ブログ

2023.09 «  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - - - - » 2023.11
TOP > CATEGORY > Rubyの文法

BACK | TOP | NEXT

Ruby のヒアドキュメント(発展編) 

2008年09月10日 ()
ヒアドキュメントについてRuby リファレンスマニュアルを参考に書いています。

今回は発展編、ということで、あまり知らなくても支障はないんじゃないか的なものの紹介です。


インデントをしている部分で、2 番目の EOS を行頭に書くとソースが汚くなる場合は <<-を使って行頭にスペースを加えることができます。

if true
  my_str =<<-EOS
    abc
    def
  EOS
end


この場合、abc や def の行頭のスペースは文字列として my_str に代入されますが、2 番目の EOS の行頭のスペースは、文字列として my_str に代入されません。
my_str = "    abc\n    def\n"


識別子(ここでは EOS を使用) をバックスラッシュで囲むとコマンドを実行します。

my_str2 =<<`EOS`
pwd
ls
cd ..;pwd
EOS




複数のヒアドキュメントを一行で指定することもできます。

date_today = "2008/09/10"
my_str3, my_str4 =<<"EOS1", <<"EOS2"
It is sunny!
Very comfy!!

#{date_today}
EOS1
I gotta clean my room.
Duhhhhh.

#{date_today}
EOS2


my_str3 には "It is sunny!\nVery comfy!!\n\n2008/09/10\n"
my_str4 には "I gotta clean my room.\nDuhhhhh.\n\n2008/09/10\n"
が入ります。


文の途中にヒアドキュメントを指定することができます。うーん、使い道があるんだろうか。

my_str5 = "<html><body>" + <<"EOS" + "</body></html>"
<p>B'z is great</p>
<p>Take 5 is nice by Kleenex</p>
<p>Take 2 is Azumax and Fukazawax</p>
EOS




ヒアドキュメントに続けてStringクラスのメソッドを書くこともできます。

aichi =<<"EOS".split("\n")
ミソカツ
えびふりゃあ
トヨタ
モーニングセット
EOS


aichi = ["ミソカツ","えびふりゃあ","トヨタ","モーニングセット"]


【広告】

[2008.09.10(Wed) 10:17] Rubyの文法Trackback(0) | Comments(2) 見る▼
↑TOPへ


COMMENT

文中のヒアドキュメント by Yugui
文の途中のヒアドキュメントはRailsのfind_by_sqlでよく使いますね。

ExampleModel.find_by_sql(<<-"SQL", {:param1 => value1, :param2 => value2)
/* 長いSQL */
SQL

おぉーありがとうございます by 自分
具体的な使い道を示していただきありがとうございます。
なるほどfind_by_sqlで使うには大変便利な機能ですね。
コメントのお礼にYuguiさんの本をこのブログのamazonスポンサー枠に掲載したいと思います!
ガッポガッポ$$$の手助けが少しでも出来ればと思います、なんちゃって。

コメントを閉じる▲

Ruby のヒアドキュメント(基礎編) 

2008年09月08日 ()
Railsから離れてRubyネタです。

ヒアドキュメントについてRuby リファレンスマニュアルを参考に、もっと簡単に説明してみよう!と思いました。(が、簡単に仕上がったのかは疑問符が付く)

ヒアドキュメントは、簡単に言うと、文字列を見やすい形で複数行に渡って書く、という機能ですね。

例1:簡単な例

my_str =<<"EOS"
  私の文字列です
EOS



これは下と全く一緒の意味なのでした。

my_str = "  私の文字列です\n"



ポイントは
・"EOS" と EOS とで文字列をはさむ
・<< と 1 番目の "EOS" の間にスペースがあってはいけない
・2 番目の EOS の行は、先頭にスペースがあってはいけない
・文字列の各行の行頭のスペースは反映される
・文字列の各行の終わりには必ず\nが付いている

ちなみに、2カ所にあるEOSですが、自分の好きな文字に変えてもOKです。abcでも123でも。しかし、EOS が良く使われるそうです。



例2:複数行もいけるよ、の例

my_str2 =<<"EOS"
私の文字列です
さらに私の文字列です
EOS



これは下と全く一緒の意味なのでした。

my_str2 = "私の文字列です\nさらに私の文字列です\n"



ちょっとー、これじゃあフツーに文字列書いたのと同じじゃないの?

my_str2 ="
私の文字列です
さらに私の文字列です
"


と思うかもしれませんが、この文字列は↓と一緒で先頭に余計な改行が入ります。

my_str2 = "\n私の文字列です\nさらに私の文字列です\n"

(さらに文字列の中に直接ダブルクォーテーションを書けないのでエスケープしなくてはならない、という制限も加わります)


例3:文字列の中で式を展開できる、の例
1 番目の EOS をダブルクォーテーションで囲むか、何も囲まないかだと文字列の中で式を展開できます。

var1 = "文字列"
my_str3 =<<"EOS"
私の#{var1}です
さらに私の#{var1}です
EOS



これは下の値が代入されます。

私の文字列です\nさらに私の文字列です\n




1 番目の EOS をシングルクォーテーションで囲むと、式が展開されません。

var1 = "文字列"
my_str3 =<<'EOS'
私の#{var1}です
さらに私の#{var1}です
EOS



これは下の値が代入されます。#{var1}が展開されません (>_<)

私の#{var1}です\nさらに私の#{var1}です\n




次回は、発展編でも書いてみようかな?

【広告】

[2008.09.08(Mon) 17:12] Rubyの文法Trackback(0) | Comments(0) 見る▼
↑TOPへ

false と nil だけが偽だそうで 

2008年07月05日 ()
Ruby レファレンスに

Ruby では false または nil だけが偽で、それ以外は 0 や空文字列も含め全て真です



とありましたが、これはなまじ他のプログラミング言語を知っていると陥りやすい落とし穴ですね。0 や 0.0 や 1 や -1 や ''(空文字列) も true と同じ扱いですものね。

特に 0 や ''(空文字列) が気をつけていないとハマリそうです。

例でみれば一目瞭然

puts '真' if true # => '真'
puts '真' if 0   # => '真'
puts '真' if ''  # => '真'
puts '真' if 0.0  # => '真'
puts '真' if 1   # => '真'
puts '真' if -1  # => '真'

puts '真' if false # =>
puts '真' if nil  # =>



【広告】

[2008.07.05(Sat) 12:33] Rubyの文法Trackback(0) | Comments(2) 見る▼
↑TOPへ


COMMENT

参考までに… by tsumuji
Lisp 属の Scheme では "#f" のみが「偽」で、それ以外はすべて「真」になります。確か、Common Lisp でも "nil" 以外は「真」になるんじゃなかったかな?

Ruby のことを "Matz Lisp" と呼ぶ人がいるくらいだから、Ruby はかなり Lisp の影響を受けて入ると思いますよ。

私は C → Ruby → Scheme の順に学習したんですが、C しか知らなかった頃と Scheme を知ってからでは Ruby の印象がガラリと変わりました。

へぇ参考になります by 自分
確かにいろんな言語を知っていくと、前に覚えた言語の印象が変わるときがありますね。リアル言語でもそうですね、例えば英語→フランス語、みたいな流れですと、うわーフランス語って男の名詞と女の名詞があるのかー、その分英語の名詞は男と女の区別がなくて楽だなー、とか。

Ruby を知る前は、nil といったらとにかく Lisp みたいな印象を強く持っていましたので、私も Ruby はモロ Lisp の要素を取り入れているのかなあ、と思っていました。

Ruby をやっていて、lambda というキーワードが出てきたときもあれどこかで昔聞いたことがあるような、と思っていたら Lisp で使ったことがあるキーワードだったのを思い出しましたし。

ところで、Ruby がここまで広まった大きな要因の 1 つとして Ruby On Rails のことを Matz さんは挙げられていましたけど、Lisp でも Lisp On Rails みたいなことは全然可能でありましょう、ともおっしゃっていました。

長い間あまり表舞台に立っていないように思えます Lisp ですが (Emacsぐらい?)、しかし消えることもなく残っているところを考えると、とてつもないポテンシャルを持っている言語で、マーケティングや時代の流れ次第では大化けするかもしれませんね。

コメントを閉じる▲

Proc.new と proc と lambda と yield と部屋とYシャツと私 

2007年12月04日 ()
今回は Ruby のバージョン 1.8.5 でお送りいたします。他バージョンでの動作は、自分で試してね、ってことで。

Javascript でいう無名関数っていうのですか、そーいうのを作るのに

Proc.new
proc
lambda

があるらしいです。例を挙げると、こんな感じ。下の例ですと、Proc.new と proc と lambda は全く同じ動きをします。call メソッドを使って定義したブロックを呼び出せます。

my_proc = Proc.new do
            puts '平松'
          end
my_proc.call # 平松 と表示される



my_proc = proc do
            puts '平松'
          end
my_proc.call # 平松 と表示される



my_proc = lambda do
            puts '平松'
          end
my_proc.call # 平松 と表示される



ということでここまでは簡単ですね。

今度は、yield っぽく使いたいという場合ですが、上記と似たようなことをします(上記と異なるのは、do ~ end がいらなくなる点)。ただし、proc と lambda の場合は、warning が表示されちゃいました。

以下をご覧ください。

def method1
  yield
end

method1 do
  puts '愛理'
end
# 愛理 と表示される
# warning は表示されない



def method1
  my_proc = Proc.new
  my_proc.call
end

method1 do
  puts '愛理'
end
# 愛理 と表示される
# warning は表示されない



def method1
  my_proc = proc # warning が出る
  my_proc.call
end

method1 do
  puts '愛理'
end
# 愛理 と表示される
# warning が表示される



def method1
  my_proc = lambda # warning が出る
  my_proc.call
end

method1 do
  puts '愛理'
end
# 愛理 と表示される
# warning が表示される



↓おまけ

def method1(&block)
  block.call
end

method1 do
  puts '愛理'
end
# 愛理 と表示される
# warning は表示されない



method1 を呼んだとき、do ~ end が隠れ引数ブロックとして method1 に渡されます。

Proc.new や、proc や lambda を使うときに、後ろに何も書かないと、この隠れ引数ブロックを使うよー、ということになります。

上記のコードでいうと
  my_proc = Proc.new # Proc.new の後ろに何も書かないと、隠れ引数ブロックを使うよー、ということ



でもでも、proc や lambda の場合は、後ろに何も書かないと、Proc.new のように、この隠れ引数ブロックを使うよー、と出来るのですが、warning が出てしまいます。

上記のコードでいうと
  my_proc = proc # proc の後ろに何も書かないと、隠れ引数ブロックを使うよー、ということにはなるが、warning が出る



という違いがありました。Rubyリファレンスマニュアルには載ってないような気がするんですけど。

まあ、普通は yield を使うのでしょうから、こういった違いに実際に遭遇する人はほとんどいないような気がしてきて虚しい師走の寒い一日でした。

趣味的にっきでは、上記とは違う観点で Proc.new と proc と lambda の相違点を説明していました。鋭い観点です。

【広告】

[2007.12.04(Tue) 15:28] Rubyの文法Trackback(0) | Comments(2) 見る▼
↑TOPへ


COMMENT

感謝 by shineble
凄く良くわかりました。ありがとうございます。
愛理ちゃんが表示されるとうれしい♪

こちらこそコメントありがとうございます by 自分
今読み返してみると、へぇー自分でこんなエントリ書いたんだ、と逆に新鮮でした。
'愛理ちゃん'がどうのこうのというコメントをいただいてこれはスパムコメントか?!と一瞬思ってしまいましたが、'愛理ちゃん'の出典元は私の記事でしたのね orz
これからもちょこちょことお立ち寄りください。

コメントを閉じる▲

yield が分からないので勉強する 

2007年11月27日 ()
rails の yield じゃなくて、ruby の yield のことなのですが、超こんがらがって分からなかったので、色々試しました。

そこで出した結論。

yield は、引数として渡されたブロックを実行するだけ



という風に今は理解しています。

どういうことか、というと例を見た方が早いと思います。

def method1
  yield
end

method1 do
  puts '血糖値'
end


を実行すると

血糖値


と表示されます。最初は、なんでこーなるの???????とハテナがたくさん付きました。

でも↓のように理解すると分かりやすくなりました。

1.
method1 do # ← この do から
  puts '血糖値'
end
# ← この end までを、1 つの引数として考える
method1 を呼んでいる箇所のうち、do ~ end までのブロック(という専門用語らしい)をまとめて method1 に渡す 1 つの引数として考える。

2.
def method1
  yield
end
の宣言は、実は「ブロック」の隠れ引数があって実際は↓のような宣言をしていることとして考える
def method1(ブロック)
  yield
end

3.
yield は、この隠れ引数の「ブロック」を実行しているだけ。




どうでしょうか。分かりやすくなったでしょうか。

yield が、隠れ引数を実行する、ということで、yield を 2 回書くと、隠れ引数を 2 回実行します。

def method1
  yield # ←yield を 2 行書いてみた
  yield # ←yield を 2 行書いてみた
end

method1 do
  puts '血糖値'
end



を実行すると、

血糖値
血糖値


と表示されます。



もちろん yield の前後に普通の ruby コードを書くこともできます。↓↓↓↓↓↓

def method1
  puts '1'
  yield
  puts '2'
  yield
  puts '3'
end

method1 do
  puts '血糖値'
end


を実行すると、

1
血糖値
2
血糖値
3


と表示されます。



そして、yield の後ろに、引数を指定しておくこともできます。

def method1
  yield(1,2,3,4) # ←引数を指定する
end

method1 do |a,b,c,d| # ←yield で指定した引数の数だけ、変数を宣言する
  puts a + b + c + d
end


を実行すると、

10



と表示されます。

もうこの段階になると、頭がこんがらがってきますが、とにかく yield は隠れ引数を実行する、ということさえ忘れなければなんとかなりそうです。



もちろん、メソッドには、隠れ引数じゃない普通の引数を指定することができます。

def method1(x,y) # ←x と y はごく普通の引数
  yield(1,2,x,y)
end

method1(100,200) do |a,b,c,d| # ←100 と 200 を普通の引数として渡す
  puts a + b + c + d
end


を実行すると、

303



と表示されます。

こりゃあ参った。何をやっているのか超大根おろしの彼女募集記念レースで訳が分かりません。↓整理するとこういう具合です。

1.x に 100 を指定して、y に 200 を指定して、更に隠れ引数(ブロック)として do ~ end を指定して、合計 3 つの引数を method1 に渡す
method1(100,200) do |a,b,c,d|
  puts a + b + c + d
end


2.method1 に引数は x と y しか宣言されていないが、隠れ引数(ブロック)がもう 1 つ実はあるので、合計 3 つの引数を取っている
def method1(x,y,ブロック)
↑みたいな

3.yield は、1 と 2 と xy を引数にして、つまり 1 と 2 と 100200 を引数にして、隠れ引数(ブロック)を実行している。

4.実行された隠れ引数(ブロック)は、a と b と c と d を引数に、つまり 1 と 2 と 100 と 200 を引数として受け取った後、それぞれを足し算して画面に表示している。



超複雑なんですけどwwwww。

でもこれでちょっと自分の中で整理がつきました。他の方の助けにもなれば、これ幸いです。

【広告】

[2007.11.27(Tue) 20:39] Rubyの文法Trackback(0) | Comments(11) 見る▼
↑TOPへ


COMMENT

わかりやすい! by グリメラ
私も「yield」が意味不明だったのでいろいろ検索してみましたが、このエントリーが一番分かりやすいと思いました。
ありがとうございました。

ありがとうございます by 自分
かなり励みになります!今夜はアルコール炭酸入り麦ジュースがうまそうです。
これからもいろんなことを共有していきたいと思います。

by -
色付きの文字すばらしい
大変分かりヤスク、すっかりしました色付きの文字

こ、これは! by 自分
テスト書き込みのようなそうでないような。ありがとうございました。

教科書に蛍光ペンでなぞるように色をつけております。
結構楽しいです。

目がテン! by -
助かりました。
はっはー。ほっほー。って感じで読みました★
はてなよりわかりやすく、少しは理解できました。
あとは、MATZがyieldを作った意図がわかればすっきりすると思います。

血糖値が高い by 自分
ありがとうございます。このエントリーを書いていた2年前の自分が救われます!
「血糖値」などという例を出していて、この頃の自分は不健康だったの?と自分に問いかけています。
島根に行脚すればMATZさんにyieldの意図が聞けるカモしれませんね。

わかりやすかったです。 by shimanp
今まで見たyieldの説明の中で一番分かりやすかったです。
おかげですっきりしました。
ありがとうございます。

よかったです by 自分
誉められて良い気分です。
yieldのメリットまで説けるようになりたいなと思っています。
ところで「大根おろしの彼女募集記念レース」はまだ健在のようです。お暇でしたらご覧になって下さい。

すごい! by ぐつ
ありがとうございます。
なんのこっちゃわからんかったのが、なんとなくですが
理解できました!
他のページ見てもさっぱりでしたので、、ほんとうに
ありがとうございました。

by ryosuke0032
非常に分かりやすかったです。初学の私には大変ありがたかったので、ぜひお礼を言わせてください。

コメントを閉じる▲
BACK | TOP | NEXT