summaryrefslogtreecommitdiff
path: root/test/ruby/test_assignment.rb
AgeCommit message (Collapse)Author
2021-04-23test/ruby/test_assignment.rb: Avoid "assigned but unused variable"Yusuke Endoh
2021-04-21Evaluate multiple assignment left hand side before right hand sideJeremy Evans
In regular assignment, Ruby evaluates the left hand side before the right hand side. For example: ```ruby foo[0] = bar ``` Calls `foo`, then `bar`, then `[]=` on the result of `foo`. Previously, multiple assignment didn't work this way. If you did: ```ruby abc.def, foo[0] = bar, baz ``` Ruby would previously call `bar`, then `baz`, then `abc`, then `def=` on the result of `abc`, then `foo`, then `[]=` on the result of `foo`. This change makes multiple assignment similar to single assignment, changing the evaluation order of the above multiple assignment code to calling `abc`, then `foo`, then `bar`, then `baz`, then `def=` on the result of `abc`, then `[]=` on the result of `foo`. Implementing this is challenging with the stack-based virtual machine. We need to keep track of all of the left hand side attribute setter receivers and setter arguments, and then keep track of the stack level while handling the assignment processing, so we can issue the appropriate topn instructions to get the receiver. Here's an example of how the multiple assignment is executed, showing the stack and instructions: ``` self # putself abc # send abc, self # putself abc, foo # send abc, foo, 0 # putobject 0 abc, foo, 0, [bar, baz] # evaluate RHS abc, foo, 0, [bar, baz], baz, bar # expandarray abc, foo, 0, [bar, baz], baz, bar, abc # topn 5 abc, foo, 0, [bar, baz], baz, abc, bar # swap abc, foo, 0, [bar, baz], baz, def= # send abc, foo, 0, [bar, baz], baz # pop abc, foo, 0, [bar, baz], baz, foo # topn 3 abc, foo, 0, [bar, baz], baz, foo, 0 # topn 3 abc, foo, 0, [bar, baz], baz, foo, 0, baz # topn 2 abc, foo, 0, [bar, baz], baz, []= # send abc, foo, 0, [bar, baz], baz # pop abc, foo, 0, [bar, baz] # pop [bar, baz], foo, 0, [bar, baz] # setn 3 [bar, baz], foo, 0 # pop [bar, baz], foo # pop [bar, baz] # pop ``` As multiple assignment must deal with splats, post args, and any level of nesting, it gets quite a bit more complex than this in non-trivial cases. To handle this, struct masgn_state is added to keep track of the overall state of the mass assignment, which stores a linked list of struct masgn_attrasgn, one for each assigned attribute. This adds a new optimization that replaces a topn 1/pop instruction combination with a single swap instruction for multiple assignment to non-aref attributes. This new approach isn't compatible with one of the optimizations previously used, in the case where the multiple assignment return value was not needed, there was no lhs splat, and one of the left hand side used an attribute setter. This removes that optimization. Removing the optimization allowed for removing the POP_ELEMENT and adjust_stack functions. This adds a benchmark to measure how much slower multiple assignment is with the correct evaluation order. This benchmark shows: * 4-9% decrease for attribute sets * 14-23% decrease for array member sets * Basically same speed for local variable sets Importantly, it shows no significant difference between the popped (where return value of the multiple assignment is not needed) and !popped (where return value of the multiple assignment is needed) cases for attribute and array member sets. This indicates the previous optimization, which was dropped in the evaluation order fix and only affected the popped case, is not important to performance. Fixes [Bug #4443] Notes: Merged: https://github.com/ruby/ruby/pull/4390 Merged-By: jeremyevans <code@jeremyevans.net>
2019-12-20Fixed misspellingsNobuyoshi Nakada
Fixed misspellings reported at [Bug #16437], only in ruby and rubyspec.
2019-09-21test/ruby/test_assignment.rb: use bug number for assert messageYusuke Endoh
to suppress variable unused warning
2019-09-20Allow calling a private accessor with `self.`Nobuyoshi Nakada
[Feature #11297] [Feature #16123] Notes: Merged: https://github.com/ruby/ruby/pull/2474
2019-08-09Fix parsing of mutiple assignment with rescue modifierJeremy Evans
Single assignment with rescue modifier applies rescue to the RHS: a = raise rescue 1 # a = (raise rescue 1) Previously, multiple assignment with rescue modifier applied rescue to the entire expression: a, b = raise rescue [1, 2] # (a, b = raise) rescue [1, 2] This makes multiple assignment with rescue modifier consistent with single assignment with rescue modifier, applying rescue to the RHS: a, b = raise rescue [1, 2] # a, b = (raise rescue [1, 2]) Implements [Feature #8239] Fixes [Bug #8279]
2018-04-17Enable the assertions that had been disabled for historical reasonmame
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63177 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-17Remove the assertions that have no meaningmame
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63176 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-08-13parse.y: chained assignmentsnobu
* parse.y (command_asgn, arg): fix syntax errors with chained assignment with op assign. [Bug #12669] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-13parse.y: massign in condnobu
* parse.y (assign_in_cond): allow multiple assignment in conditional expression. [Feature #10617] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-01-10compile.c: fix lhs splat in massignnobu
* compile.c (compile_massign_lhs): when index ends with splat, append rhs value to it like POSTARG, since VM_CALL_ARGS_SPLAT splats the last argument only. [ruby-core:72777] [Bug #11970] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-16Add frozen_string_literal: false for all filesnaruse
When you change this to true, you may need to add more tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53141 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-04-30compile.c: disallow private readersnobu
* compile.c (iseq_compile_each): revert r46873 and r46875, not to allow to execute private readers by pretending op assign. [ruby-core:68984] [Bug #11096] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-07-19compile.c: private reader in op_assignnobu
* compile.c (iseq_compile_each): allow to access private attribute reader in op_assign. [ruby-core:63817] [Bug #10060] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46873 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-06-06compile.c, parse.y: private op assignnobu
* compile.c (iseq_compile_each), parse.y (new_attr_op_assign_gen): allow op assign to a private attribute. [ruby-core:62949] [Bug #9907] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46365 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-06-06test_assignment.rb: assignment to private attributenobu
* test/ruby/test_assignment.rb (test_assign_private_self): test for r3509, assignment to private attribute is allowed iff its receiver is literal `self`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-06-06test_assignment.rb: split test_assignnobu
* test/ruby/test_assignment.rb (test_assign): split by assignment forms. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46363 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-01-25compile.c: assignment result of aset_withnobu
* compile.c (iseq_compile_each): result of assignment should be its rhs instead of returned value from a method. [ruby-core:60071] [Bug #9448] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44705 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-09-18* compile.c (iseq_compile_each), parse.y (stmt, arg): arg_concat()nobu
on op_asgn was inversed. [ruby-core:25629] [Bug #2050] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-04-12* prelude.rb (require_relative): move require_relative frommatz
lib/require_relative.rb. [ruby-core:16356] * lib/require_relative.rb: removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15985 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-02-18use require_relative to require marshaltestlib and sentence.akr
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15540 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-11-04* eval.c (rb_f_send): allow send/__send__ to call methods of allmatz
visibility again. we no longer provide __send, __send!. * eval.c (rb_invoke_method): new method to honor private visibility. if it's invoked in a function call style, it calls private methods as well (previous 1.9 send behavior). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13824 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-25test assignment order.akr
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13260 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24* test/ruby/sentence.rb (Sentence): include Enumerable.akr
(Sentence#each): defined. * test/ruby/test_assignment.rb: use Sentence#expand. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13253 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-18sentence.rb documented.akr
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-18* test/ruby/test_yield.rb (TestYieldGen): add test for yielding toakr
lambda using lambda parameter passing emulator. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13087 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-16* test/ruby/sentence.rb: Sentence class implementedakr
based on sentgen.rb * test/ruby/sentgen.rb: removed. * test/ruby/test_assignment.rb: use sentence.rb. * test/ruby/test_yield.rb: block parameter passing emulator implemented. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13064 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-08variable renaming refined.akr
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12904 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-13sentence generator updated.akr
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12762 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-06* test/ruby/sentgen.rb: new file.akr
* test/ruby/test_assignment.rb: tests implemeneted using assignment generator and emulator. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12709 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-15* vm.c (th_yield_setup_args): |v| should work as |v,|.ko1
ex) def m;yield 1, 2; end; m{|v| p v} #=> 1 * parse.y: apply above change for "for" statement. * test/ruby/test_assignment.rb: ditto * test/ruby/test_basicinstructions.rb: ditto. * test/ruby/test_iterator.rb: ditto. * test/ruby/test_yield.rb: ditto. * compile.c (iseq_compile_each): fix debug. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12544 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-23* test/ruby/test_assignment.rb: merge yarvtest/test_massign.aamine
* yarvtest/test_massign.rb: removed (merged to test_assignment.rb). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11830 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-07-10* sample/test.rb: update test suites.matz
* test/ruby/test_assignment.rb (TestAssignment::test_yield): ditto. * test/ruby/test_iterator.rb (TestIterator::test_itertest): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09* sprintf.c (rb_str_format): allow %c to print one charactermatz
string (e.g. ?x). * lib/tempfile.rb (Tempfile::make_tmpname): put dot between basename and pid. [ruby-talk:196272] * parse.y (do_block): remove -> style block. * parse.y (parser_yylex): remove tLAMBDA_ARG. * eval.c (rb_call0): binding for the return event hook should have consistent scope. [ruby-core:07928] * eval.c (proc_invoke): return behavior should depend whether it is surrounded by a lambda or a mere block. * eval.c (formal_assign): handles post splat arguments. * eval.c (rb_call0): ditto. * st.c (strhash): use FNV-1a hash. * parse.y (parser_yylex): removed experimental ';;' terminator. * eval.c (rb_node_arity): should be aware of post splat arguments. * eval.c (rb_proc_arity): ditto. * parse.y (f_args): syntax rule enhanced to support arguments after the splat. * parse.y (block_param): ditto for block parameters. * parse.y (f_post_arg): mandatory formal arguments after the splat argument. * parse.y (new_args_gen): generate nodes for mandatory formal arguments after the splat argument. * eval.c (rb_eval): dispatch mandatory formal arguments after the splat argument. * parse.y (args): allow more than one splat in the argument list. * parse.y (method_call): allow aref [] to accept all kind of method argument, including assocs, splat, and block argument. * eval.c (SETUP_ARGS0): prepare block argument as well. * lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931] * eval.c (error_line): print receivers true/false/nil specially. * eval.c (rb_proc_yield): handles parameters in yield semantics. * eval.c (nil_yield): gives LocalJumpError to denote no block error. * io.c (rb_io_getc): now takes one-character string. * string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo hashing algorithm. * string.c (rb_str_aref): str[0] now returns 1 character string, instead of a fixnum. [Ruby2] * parse.y (parser_yylex): ?c now returns 1 character string, instead of a fixnum. [Ruby2] * string.c (rb_str_aset): no longer support fixnum insertion. * eval.c (umethod_bind): should not update original class. [ruby-dev:28636] * eval.c (ev_const_get): should support constant access from within instance_eval(). [ruby-dev:28327] * time.c (time_timeval): should round for usec floating number. [ruby-core:07896] * time.c (time_add): ditto. * dir.c (sys_warning): should not call a vararg function rb_sys_warning() indirectly. [ruby-core:07886] * numeric.c (flo_divmod): the first element of Float#divmod should be an integer. [ruby-dev:28589] * test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder. * re.c (rb_reg_initialize): should not allow modifying literal regexps. frozen check moved from rb_reg_initialize_m as well. * re.c (rb_reg_initialize): should not modify untainted objects in safe levels higher than 3. * re.c (rb_memcmp): type change from char* to const void*. * dir.c (dir_close): should not close untainted dir stream. * dir.c (GetDIR): add tainted/frozen check for each dir operation. * lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg): typo fixed. a patch from Florian Gross <florg at florg.net>. * eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from event_hooks. no guarantee for arbitrary hook deletion. [ruby-dev:28632] * util.c (ruby_strtod): differ addition to minimize error. [ruby-dev:28619] * util.c (ruby_strtod): should not raise ERANGE when the input string does not have any digits. [ruby-dev:28629] * eval.c (proc_invoke): should restore old ruby_frame->block. thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833] also fix [ruby-dev:28614] as well. * signal.c (trap): sig should be less then NSIG. Coverity found this bug. a patch from Kevin Tew <tewk at tewk.com>. [ruby-core:07823] * math.c (math_log2): add new method inspired by [ruby-talk:191237]. * math.c (math_log): add optional base argument to Math::log(). [ruby-talk:191308] * ext/syck/emitter.c (syck_scan_scalar): avoid accessing uninitialized array element. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07809] * array.c (rb_ary_fill): initialize local variables first. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810] * ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free type_tag. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07808] * ext/socket/socket.c (make_hostent_internal): accept ai_family check from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07691] * util.c (ruby_strtod): should not cut off 18 digits for no reason. [ruby-core:07796] * array.c (rb_ary_fill): internalize local variable "beg" to pacify Coverity. [ruby-core:07770] * pack.c (pack_unpack): now supports CRLF newlines. a patch from <tommy at tmtm.org>. [ruby-dev:28601] * applied code clean-up patch from Stefan Huehner <stefan at huehner.org>. [ruby-core:07764] * lib/jcode.rb (String::tr_s): should have translated non squeezing character sequence (i.e. a character) as well. thanks to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090] * ext/socket/socket.c: document update patch from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07701] * lib/mathn.rb (Integer): need not to remove gcd2. a patch from NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570] * parse.y (arg): too much NEW_LIST() * eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen. * eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1. [ruby-dev:28585] * parse.y (arg): use NODE_ARGSCAT for placeholder. * lib/getoptlong.rb (GetoptLong::get): RDoc update patch from mathew <meta at pobox.com>. [ruby-core:07738] * variable.c (rb_const_set): raise error when no target klass is supplied. [ruby-dev:28582] * prec.c (prec_prec_f): documentation patch from <gerardo.santana at gmail.com>. [ruby-core:07689] * bignum.c (rb_big_pow): second operand may be too big even if it's a Fixnum. [ruby-talk:187984] * README.EXT: update symbol description. [ruby-talk:188104] * COPYING: explicitly note GPLv2. [ruby-talk:187922] * parse.y: remove some obsolete syntax rules (unparenthesized method calls in argument list). * eval.c (rb_call0): insecure calling should be checked for non NODE_SCOPE method invocations too. * eval.c (rb_alias): should preserve the current safe level as well as method definition. * process.c (rb_f_sleep): remove RDoc description about SIGALRM which is not valid on the current implementation. [ruby-dev:28464] Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp> * eval.c (method_missing): should support argument splat in super. a bug in combination of super, splat and method_missing. [ruby-talk:185438] * configure.in: Solaris SunPro compiler -rapth patch from <kuwa at labs.fujitsu.com>. [ruby-dev:28443] * configure.in: remove enable_rpath=no for Solaris. [ruby-dev:28440] * ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby String object. * ruby.1: a clarification patch from David Lutterkort <dlutter at redhat.com>. [ruby-core:7508] * lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems directories. a patch from Eric Hodel <drbrain at segment7.net>. [ruby-core:07423] * eval.c (rb_clear_cache_by_class): clearing wrong cache. * ext/extmk.rb: use :remove_destination to install extension libraries to avoid SEGV. [ruby-dev:28417] * eval.c (rb_thread_fd_writable): should not re-schedule output from KILLED thread (must be error printing). * array.c (rb_ary_flatten_bang): allow specifying recursion level. [ruby-talk:182170] * array.c (rb_ary_flatten): ditto. * gc.c (add_heap): a heap_slots may overflow. a patch from Stefan Weil <weil at mail.berlios.de>. * eval.c (rb_call): use separate cache for fcall/vcall invocation. * eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local functions. * eval.c (rb_mod_local): a new method to specify newly added visibility "local". * eval.c (search_method): search for local methods which are visible only from the current class. * class.c (rb_class_local_methods): a method to list local methods. * object.c (Init_Object): add BasicObject class as a top level BlankSlate class. * ruby.h (SYM2ID): should not cast to signed long. [ruby-core:07414] * class.c (rb_include_module): allow module duplication. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-10-08* lib/scanf.rb (Scanf::FormatSpecifier#letter, #width): use matchednobu
substring directly. * ext/nkf/lib/kconv.rb (Kconv.conv): get rid of nil.to_a. * test/ruby/test_assignment.rb, test/ruby/test_iterator.rb: followed change of sample/test.rb. * test/net/http/test_http.rb: removed superfluous splatting stars. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9360 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2004-03-03* ext/syck/rubyext.c: get rid of warnings.nobu
* lib/rss/taxonomy.rb: ditto. * lib/rdoc/ri/ri_formatter.rb: ditto. * test/ruby/test_assignment.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5882 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2004-02-18 * test/*: should not depend on $KCODE.nahi
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-10-29* eval.c (proc_invoke): single array value to normal Proc#callmatz
(i.e. not via lambda call), should be treated just like yield. [ruby-dev:21726] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-10-28* parse.y (new_yield): remove magic argument rule; "yield [1,2]"matz
should yield single array of two elements, not two values. [ruby-dev:21726] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4848 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-09-05* lib/optparse.rb (OptionParser#order, #permute, #parse): allow annobu
array as argument. * test/ruby/test_*.rb: moved invariants to left side in assert_equal, and use assert_nil, assert_raises and so on. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4516 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-09-05* test/ruby/test_*.rb: replace 'assert(a == b)' with assert_equal(a, b)'nahi
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4512 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-09-04* test/ruby: tests for ruby itself.nahi
* test/ruby/test_*.rb: split sample/test.rb into 28 test/unit testcases. some tests could not be translates... search '!!' mark to see it. * test/csv/test_csv.rb: should require 'csv', not '../lib/csv'. test runner should set load path correctly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4498 b2dd03c8-39d4-4d8f-98ff-823fe69b080e