Anonymous Struct Literals Might Be Coming To Ruby

栏目: IT技术 · 发布时间: 3年前

内容简介:There’s been some really interesting discussion in the Ruby community about adding anonymous struct literals to the language. My Japanese isn’t very good (I don’t speak Japanese), but Koichi Sasada and Matz had a little Twitter exchange about the idea and

There’s been some really interesting discussion in the Ruby community about adding anonymous struct literals to the language. My Japanese isn’t very good (I don’t speak Japanese), but Koichi Sasada and Matz had a little Twitter exchange about the idea and that’s now turned into a proposal on the Ruby tracker where there’s been further discussion.

@yukihiro_matz just idea なんですが、無名Structを簡単に作る仕組みをいれるのはどうでしょうか。同じキーセットなら、同じ無名 Struct が返るような感じで。 pic.twitter.com/OfP6YigiYq

— _ko1 (@_ko1) June 25, 2020

What’s a Struct?

Ruby provides Structs as a convenient way to create classes that group together a set of fields without forcing you to explicitly define a class with all the accessor methods.

For example, if you needed to pass around a representation of a dog but didn’t need any additional behaviour you might do something like this:

[1] pry(main)> Dog = Struct.new(:name, :breed, :age)
=> Dog
[2] pry(main)> roxie = Dog.new("Roxie", "whippet-cross", 4)
=> #<struct Dog name="Roxie", breed="whippet-cross", age=4>
[3] pry(main)> roxie.name
=> "Roxie"
[4] pry(main)> roxie.breed
=> "whippet-cross"
[5] pry(main)> roxie.age
=> 4
[6] pry(main)> roxie.age = 5
=> 5
[7] pry(main)> roxie2 = Dog.new("Roxie", "whippet-cross", 5)
=> #<struct Dog name="Roxie", breed="whippet-cross", age=5>
[8] pry(main)> roxie == roxie2
=> true

Because instances of Structs are equal if their attributes are all equal, it makes them a great solution for defining value objects .

What does the proposal add?

There’s some disagreement on the syntax, but the idea is to add a syntax for defining anonymous instances of Structs in-line. Today, you might write this:

roxie = Struct.new(:name, :breed).new(
  "Roxie",
  "whippet-cross"
)

With this proposal you’d be able to simply write something like this instead:

roxie = ${name: "Roxie", breed: "whippet-cross"}

This would create an instance of an anonymous Struct class without having to explicitly define and instantiate the class.

Why is that useful?

There are actually a number of benefits to this, but let’s start with why anonymous Structs are useful regardless of the syntax.

Structs avoid typos

In Ruby we often use hashes for passing around things like configuration options and other structured data. Structs allow us to do this without allowing arbitrary properties.

In our dog example above, roxie.breeed = "pug" will cause an error because we spelled “breed” incorrectly and the Struct doesn’t have a member called “breeed”. If were using a Hash instead then we’d be able to accidentally assign roxie[:breeed] = "pug" without any errors, accidentally creating a new typoed key in the Hash.

There are many cases where you need arbitrary properties, but for those cases you can use OpenStruct or a Hash. When accepting configuration from a user or any other situation where you know the possible fields in advance Structs work great.

Anonymous Structs communicate intent

Writing code that communicates its own intent clearly is useful for helping future developers understand and modify that code. Using an anonymous Struct rather than a Hash or OpenStruct communicates to the person reading the code that the fields the object is defined with are the only fields that object supports.

Structs are simpler to access

This is admittedly a small improvement, but it’s simpler to type roxie.breed than roxie[:breed] . In this example roxie doesn’t represent an arbitrary mapping of keys to values, but a dog, so if we’re following conventional object-oriented design practices, then roxie should be an object that responds to messages about itself.

Using Structs over Hashes also means that refactoring the code to use a real Class won’t mean you need to change everywhere its data is accessed.

OpenStruct is slow

OpenStruct is another class in the standard library that provides the ability to create objects that are basically like Structs, but are “open” to creating new attributes like Hashes are.

This is extremely useful if you need to support arbitrary attributes on the object, but if you don’t you’re just opening yourself up to the same issue as using a Hash:

[1] pry(main)> roxie = OpenStruct.new(name: "Roxie", breed: "whippet-cross")
=> #<OpenStruct name="Roxie", breed="whippet-cross">
[2] pry(main)> roxie.breeed = "french bulldog"
=> "french bulldog"
[3] pry(main)> roxie
=> #<OpenStruct name="Roxie", breed="whippet-cross", breeed="french bulldog">

Additionally, while OpenStructs are definitely great when you need their “open” functionality, they are much slower than regular Structs. Koichi Sasada notes this in the performance section of his proposal.

But it says in the proposal that Hashes are faster!

One interesting detail that the proposal brings up is that Hashes are currently faster than Structs for this kind of usage. This is true, but Hashes have seen plenty of optimization because of how heavily we rely on them.

You would think that Structs would be faster than Hashes since their behaviour is simpler. Well, that’s not the case but Koichi Sasada is confident that it could be the case with some optimization.

This proposal also enables a whole new optimization that is only briefly mentioned:

Thanks to this spec, we can specify anonymous Struct classes at compile time. We don’t need to find or create Struct classes at runtime.

Because the attributes of the Structs is known at parse time rather than run time, it is possible to define the anonymous classes at compile time so that using this syntax incurs only the overhead of instantiating the anonymous class without having to define it too.

What does it mean for you?

For now, not much. We can’t use this in our programs yet, but we are free to use anonymous Structs in our code without the special syntax. If you’re creating value objects, want to limit the attributes on your object, or just want to make refactoring easier, this isn’t a bad idea.

That said, keep an eye on this proposal. Switching to this syntax in your applications when it becomes available could have performance benefits, save on typos, and make your code clearer.

What do you think about this new syntax? Let me know on Twitter!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web前端黑客技术揭秘

Web前端黑客技术揭秘

钟晨鸣、徐少培 / 电子工业出版社 / 2013-1 / 59.00元

Web前端的黑客攻防技术是一门非常新颖且有趣的黑客技术,主要包含Web前端安全的跨站脚本(XSS)、跨站请求伪造(CSRF)、界面操作劫持这三大类,涉及的知识点涵盖信任与信任关系、Cookie安全、Flash安全、DOM渲染、字符集、跨域、原生态攻击、高级钓鱼、蠕虫思想等,这些都是研究前端安全的人必备的知识点。本书作者深入剖析了许多经典的攻防技巧,并给出了许多独到的安全见解。 本书适合前端工......一起来看看 《Web前端黑客技术揭秘》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具