`
love~ruby+rails
  • 浏览: 852364 次
  • 性别: 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.
分享到:
评论

相关推荐

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

    资源分类:Python库 所属语言:Python 使用前提:需要解压 资源全名:zha_quirks-0.0.47-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    quirksmode

    浏览器 Quirksmode(怪异模式)与 CSS1compat 浏览器 Quirksmode(怪异模式)与 CSS1compat 是一种浏览器渲染模式的概念,它们之间存在着一些区别和联系。Quirksmode 也称为 Compatibility Mode,是一种非标准的渲染...

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

    在“IE Quirks模式”下,这个库表现得相当出色,解决了许多浏览器兼容性问题,尤其是针对老版本的Internet Explorer。 "Quirks模式"是Internet Explorer早期版本为了向后兼容老版网页而设立的一种渲染模式。在该...

    hid-quirks.rar_linux usb hid

    3. Quirk检查:驱动在初始化阶段会查看hid-quirks.c文件,寻找匹配的设备ID及其quirks。 4. 应用quirks:如果找到匹配的quirks,驱动将按照quirk定义调整其行为。 5. 设备操作:驱动现在按照修正后的逻辑与设备交互...

    conf_space_quirks.rar_space

    3. **conf_space_quirks.c**: 这个源代码文件很可能包含了处理quirks的实际函数和逻辑。它会根据设备的标识符或特定条件来应用相应的quirk处理程序,以确保这些设备能正常工作。代码可能会包含一系列if-else语句或...

    pci-quirks.rar_generations

    "pci-quirks.rar_generations"这个压缩包很可能包含了与AMD芯片组不同代别相关的PCI设备quirks处理代码。 在描述中提到的"amd_chipset_gen values"代表AMD的不同芯片组世代。AMD是一家知名的半导体公司,其芯片组在...

    pdata-quirks.rar_legacy

    在IT行业中,"pdata-quirks.rar_legacy"这个标题暗示了一个关于旧版(legacy)平台数据(platform_data)特性的讨论。"quirks"一词通常指的是设备或系统中的异常行为,这些行为可能源于硬件设计的缺陷或者是为了兼容...

    pci-quirks.rar_amd_generations

    标题 "pci-quirks.rar_amd_generations" 暗示了这是一份与AMD(Advanced Micro Devices)芯片组相关的技术文档,特别是涉及到PCI(Peripheral Component Interconnect)接口的异常处理,即“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

    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 ...

    Microsoft Outlook 2007 Programming: Jumpstart for Power Users and Administrators Sample chapters:Chapter 1 - What You Can Do with Outlook 2007 (PDF, 794kb)

    Even if you have never programmed before, this book provides the basics needed to get started. Programming Outlook is much easier than you might think. For experienced programmers, the book covers ...

    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并测试想法。 此扩展程序吸引了好奇和恶作剧的人,他们不禁与那些不太懂技术的朋友...

    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 ...

    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 ...

Global site tag (gtag.js) - Google Analytics