Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is a patch to Ruby 2.5.0 to enable es6 like hash literals - instructions in the comments
From a034498e36c02715b9201646d4ce1ddcddf118c3 Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Wed, 29 Apr 2015 09:14:15 +0900
Subject: [PATCH] support ES6-like hash literals.
---
parse.y | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 72 insertions(+), 17 deletions(-)
diff --git a/parse.y b/parse.y
index 7e85d70..dd03433 100644
--- a/parse.y
+++ b/parse.y
@@ -477,6 +477,10 @@ static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
#define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
+static NODE *assoc_concat_gen(struct parser_params*,NODE*,NODE*);
+#define assoc_concat(assocs,tail) assoc_concat_gen(parser,(assocs),(tail))
+static ID var_to_assoc_key(ID);
+
#define get_id(id) (id)
#define get_value(val) (val)
#else
@@ -820,7 +824,7 @@ static void token_info_pop(struct parser_params*, const char *token);
%type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
%type <node> f_block_optarg f_block_opt
%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
-%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
+%type <node> assoc_list assoc_items assoc_item assocs assoc undef_list backref string_dvar for_var
%type <node> block_param opt_block_param block_param_def f_opt
%type <node> f_kwarg f_kw f_block_kwarg f_block_kw
%type <node> bv_decls opt_bv_decl bvar
@@ -5019,7 +5023,7 @@ singleton : var_ref
;
assoc_list : none
- | assocs trailer
+ | assoc_items trailer
{
/*%%%*/
$$ = $1;
@@ -5029,6 +5033,38 @@ assoc_list : none
}
;
+assoc_items : assoc_item
+ /*%c%*/
+ /*%c
+ {
+ $$ = rb_ary_new3(1, $1);
+ }
+ %*/
+ | assoc_items ',' assoc_item
+ {
+ /*%%%*/
+ $$ = assoc_concat($1, $3);
+ /*%
+ $$ = rb_ary_push($1, $3);
+ %*/
+ }
+ ;
+
+assoc_item : assoc
+ | user_variable
+ {
+ /*%%%*/
+ ID k = var_to_assoc_key($1);
+ NODE *key, *val;
+ key = NEW_LIT(ID2SYM(k));
+ if (!(val = gettable($1, &@$))) val = NEW_BEGIN(0);
+ $$ = list_append(NEW_LIST(key), val);
+ /*%
+ $$ = dispatch2(assoc_new, $1, id_is_var(get_id($1)) ? dispatch1(var_ref, $1) : dispatch1(vcall, $1));
+ %*/
+ }
+ ;
+
assocs : assoc
/*%c%*/
/*%c
@@ -5039,21 +5075,7 @@ assocs : assoc
| assocs ',' assoc
{
/*%%%*/
- NODE *assocs = $1;
- NODE *tail = $3;
- if (!assocs) {
- assocs = tail;
- }
- else if (tail) {
- if (assocs->nd_head &&
- !tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
- nd_type(tail->nd_next->nd_head) == NODE_HASH) {
- /* DSTAR */
- tail = tail->nd_next->nd_head->nd_head;
- }
- assocs = list_concat(assocs, tail);
- }
- $$ = assocs;
+ $$ = assoc_concat($1, $3);
/*%
$$ = rb_ary_push($1, $3);
%*/
@@ -10439,6 +10461,39 @@ rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALU
return re;
}
+static NODE *
+assoc_concat_gen(struct parser_params *parser, NODE *assocs, NODE *tail)
+{
+ if (!assocs) {
+ assocs = tail;
+ }
+ else if (tail) {
+ if (assocs->nd_head &&
+ !tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
+ nd_type(tail->nd_next->nd_head) == NODE_HASH) {
+ /* DSTAR */
+ tail = tail->nd_next->nd_head->nd_head;
+ }
+ assocs = list_concat(assocs, tail);
+ }
+ return assocs;
+}
+
+static ID var_to_assoc_key(ID var)
+{
+ switch (id_type(var)) {
+ case ID_LOCAL:
+ case ID_CONST:
+ return var;
+ default: {
+ const char *name = rb_id2name(var);
+ while (*name == '$' || *name == '@')
+ name++;
+ return rb_intern(name);
+ }
+ }
+}
+
NODE*
rb_parser_append_print(VALUE vparser, NODE *node)
{
--
1.9.1
@thechrisoshow

This comment has been minimized.

Show comment
Hide comment
@thechrisoshow

thechrisoshow Feb 20, 2018

Ever wanted to have cool es6 style hash literals in Ruby?

e.g.

params = { name, email }
#=> { name: name, email: email }

The easiest way that I implemented this is by using rvm. Download this patch onto your computer and use rvm to install like this:

rvm install 2.5.0 -n imphash --patch imphash.patch

This will install a version of Ruby on your machine called ruby-2.5.0-imphash. You can select this if you want the fun es6 literals.

BIG NOTE
I did NOT create this patch. This was created by Shugo Maeda in 2015.
(Here's the original patch: https://bugs.ruby-lang.org/attachments/5194/0001-support-ES6-like-hash-literals.patch)

I only made one tiny change to make it work with the latest version of ruby.

Little note
Imphash is short for "implicit hash" - and cause I don't know what these are called I thought that could be good one.

Owner

thechrisoshow commented Feb 20, 2018

Ever wanted to have cool es6 style hash literals in Ruby?

e.g.

params = { name, email }
#=> { name: name, email: email }

The easiest way that I implemented this is by using rvm. Download this patch onto your computer and use rvm to install like this:

rvm install 2.5.0 -n imphash --patch imphash.patch

This will install a version of Ruby on your machine called ruby-2.5.0-imphash. You can select this if you want the fun es6 literals.

BIG NOTE
I did NOT create this patch. This was created by Shugo Maeda in 2015.
(Here's the original patch: https://bugs.ruby-lang.org/attachments/5194/0001-support-ES6-like-hash-literals.patch)

I only made one tiny change to make it work with the latest version of ruby.

Little note
Imphash is short for "implicit hash" - and cause I don't know what these are called I thought that could be good one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment