`
love~ruby+rails
  • 浏览: 829941 次
  • 性别: Icon_minigender_1
  • 来自: lanzhou
社区版块
存档分类
最新评论

3 Ruby Quirks You Have to Love

阅读更多
Ruby’s a fantastic language; we love it because it’s flexible, readable and concise, to name just a few reasons. The Ruby language is also incredibly complex as far as language syntaxes (grammar) are concerned. This sometimes leads to some dark seedy corners… but by examining the stranger aspects of Ruby’s syntax, it helps us to better understand the power of Ruby. This entry will show some of the stranger aspects of the language and reflect on how we rarely see these used in real life.

Warning: Most of the code you see in this post should never be used in real life by actual programmers. The snippets are meant to provide insight into the power of Ruby, and more obviously, are for entertainment value.
1. Expressions are Cool

One of the great things about Ruby is that everything is just executable code. In fact, everything is an expression. This makes it nice because you can then programmatically build up a set of methods in a class body, like this:

class Numeric
  MM_SIZE = 0.00025

  [:mm, :cm, :dm, :m, :dam, :hm, :km, :Mm].inject(MM_SIZE) do |size, unit|
    define_method(unit) { self * size }
    size * 10
  end
end

Ignoring the fact that I just modified Numeric, you have to admit that being able to do stuff like this in Ruby makes it a great language; a language with the flexibility to define methods progammatically because everything is just code and expressions.

Over the years of supporting JRuby, I began to realize that the grammar is a bit too too generous. At this point you can argue that it’s up to programmers to hang themselves with any bizarre language feature. So what’s the fuss?

def foo(a, b=def foo(a); "F"; end)
  a
end

p foo("W", 1) + foo("T") + foo("bar")      # => "WTF"

Is there a sane reason to allow a def as the value of an optional argument? Since we have a language where everything is an expression, this is just life in the Ruby lane. Luckily, def returns nil and not UnboundMethod or something that’s considered useful; otherwise there would be some pretty weird code floating around.

Before I go on, I wondered about variable scoping…

def foo(a, b = self.class.send(:define_method, :foo) {|_| ": I captured #{a}" })
  a
end

p foo("foo") + foo("bar")  #=> foo: I captured foo

Of course it makes sense that the optional argument value of ‘b’ evaluates in a scope where it can capture ‘a’… but wow! The potential for strange Ruby code is just amazing!
2. It Makes Sense But…

Other times the grammar has oddities which seem to make sense on the surface but generally confuse you when you start to stray off the path of idiomatic Ruby. Heredocs are a great example:

a = <<EOF
hooray
multi-lines
EOF

This how we normally see them. The idiomatic example may have us define a heredoc as: when encountering a heredoc statement (<<EOF) take all lines after that statement until we encounter the heredoc marker on a line by itself and use those lines as a multi-line string. Certainly, that would still work for this example:

{:skybox => "/data/skyboxes/mountains/",
:floors => [
  {:location => [0,0,0],:data => <<EOL, :texture => "data/texture/wall.jpg"},
........BCB.........
.........P..........
....................
........DDD.........
.......D....D.......
....................
....D.....D....D....
....................
..D....D....D....D..
...BBBBBBBBBBBBBB...
EOL
  {:location => [0,10,0],:data => <<EOL, :texture => "data/texture/wall.jpg"},
# More elided ...
}

Heredocs in this code are interleaved in the middle of a hash literal… This is odd, but the definition still holds up. Let’s break the definition:

def foo(a,b)
  p a, b
end

foo(<<ONE, <<TWO)
This is one
ONE
This is two
TWO

Two heredocs on the same line break the definition. I think with a little work we could fix the definition to talk about what to do about multiple heredocs on the same line, but then consider this case:

a = <<ONE
This is one. #{<<TWO}
This is two. #{<<THREE}
This is three.
THREE
TWO
ONE    # => "This is one. This is two. This is three.\n\n\n"

Coming up with an easy to read definition is starting to get rough. Maybe just accepting that you can do weird things with heredoc without actually explaining them in a common definition is the right thing to do. Do we really want people to use heredocs this way? Is it cool that we can do stuff like this?
3. Mystical String Concatenation

Ruby’s grammar is huge. Super huge, and sometimes you see something in the grammar that makes you wonder how it got there. For me the one I wonder about the most is what I call the “Mystical String Concatenation” feature:

string        : string1
              | string string1 {
                  $$ = support.literal_concat(getPosition($1), $1, $2);
              }

Since string1 must be a type of string literal this translates into the following Ruby syntax:

a = "foo" "bar"
p a # => "foobar"

Is this really useful? The performance benefit is that the parser will concatenate the string before any execution happens…. but this only works for string literals! A programmer could just rewrite the string as “foobar”. Perhaps someone wanted to inspect strings into an eval statement?

one = "foo"
two = "bar"
a = eval "#{one.inspect} #{two.inspect}"

It mystifies me…
Conclusion

Ruby is beautiful, powerful, and in some cases, wacky. I’ve only just scratched the surface of the weird convoluted things you can do with Ruby’s syntax. What’s most interesting to me though is that Ruby programmers rarely touch these strange bits unless they’re trying to be cute…

Compared to another language I used to always use (it starts with a P and is four letters, but I seem to have completely forgotten its name…), it’s surprising how rarely real Ruby code ventures into the land of the indecipherable.

Both Ruby and the previously mentioned forgotten language are very powerful, and can get a lot of the same things done, but it seems that Ruby code ends up being written in a largely idiomatic way. Ruby may be a rat’s nest for writing a coherent specification of the language, but the Ruby that people write using this underspecified language ends up looking really nice.
分享到:
评论

相关推荐

    quirksmode

    浏览器Quirksmode(怪异模式)与CSS1compat.docx

    Python库 | zha_quirks-0.0.47-py3-none-any.whl

    python库。 资源全名:zha_quirks-0.0.47-py3-none-any.whl

    pdata-quirks.rar_legacy

    Legacy platform_data quirks.

    Python库 | zha_quirks-0.0.63-py3-none-any.whl

    python库,解压后可用。 资源全名:zha_quirks-0.0.63-py3-none-any.whl

    PyPI 官网下载 | zha_quirks-0.0.63-py3-none-any.whl

    资源来自pypi官网。 资源全名:zha_quirks-0.0.63-py3-none-any.whl

    prettyPhoto---IE Quirks模式下的弹出窗口的好选择

    NULL 博文链接:https://theoffspring.iteye.com/blog/1582300

    Java Cook Book

    Unlike my Perl colleagues Tom and Nathan, I don't have to spend as much time on the oddities and idioms of the language; Java is refreshingly free of strange quirks. But that doesn't mean it's ...

    Python库 | zha_quirks-0.0.59-py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:zha_quirks-0.0.59-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Chrome Quirks-crx插件

    Chrome Quirks是一个有趣的扩展程序,可让您将预加载的效果或自定义CSS注入到您访问的任何网页上。 开发人员可以快速轻松地编辑CSS并测试想法。 此扩展程序吸引了好奇和恶作剧的人,他们不禁与那些不太懂技术的朋友...

    hid-quirks.rar_linux usb hid

    USB HID quirks support for Linux.

    Advanced R 原版PDF by Wickham

    With more than 10 years experience ...process, I hope to show that, despite its frustrating quirks, R is, at its heart, an elegant and beautiful language, well tailored for data analysis and statistics

    OpenCart v1.4.8

    This version of opencart comes with a universal upgrade script that allows you to update your store from as far back as v1.3.2 to the latest version of OpenCart without having to install each version ...

    Hello.Android.3rd.Edition

    Whether you’re a hobbyist or a professional programmer, whether you are doing it for fun or for profit, it’s time to learn more about developingfor Android. This book will help you get started.  ...

    quirks:怪癖模式标准

    简而言之,请更改quirks.bs并提交您的补丁,并附带一条。 如果您是这里的新手,请考虑阅读。 即使是微不足道的修复,也请在您的第一个请求请求中的“确认”部分添加您的名字。 名称按字典顺序排序。 在“本地”构建...

    Efficiency Guide (erlang)

    you should profile the application to find out where the performance bottlenecks are and optimize only the bottlenecks. Other code should stay as clean as possible. Fortunately, compiler and run-time ...

    Java解惑.中文完整版

    Have you ever spent days chasing a bug caused by a trap or pitfall in Java or its libraries? Do you like brainteasers? Then this is the book for you! In the tradition of Effective Java(t), Bloch and ...

    浏览器Quirksmode模式与CSSCompat模式

    (资料备考 暂时不明白也无关系) 今天偶然看到了一道题中有这样一段: 在不同浏览器的Quirksmode和CSSCompat模式下都保持同一效果 其实对于学习标准的人可能更多的人熟悉Quirksmode,也许很多人(对JS不太熟悉的...

Global site tag (gtag.js) - Google Analytics