Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
f962890a
Commit
f962890a
authored
9 years ago
by
Blaž Hrastnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement Module#prepend.
parent
d0e67aad
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
2 deletions
+99
-2
include/mruby/class.h
include/mruby/class.h
+1
-0
src/class.c
src/class.c
+65
-2
test/t/module.rb
test/t/module.rb
+33
-0
No files found.
include/mruby/class.h
View file @
f962890a
...
...
@@ -16,6 +16,7 @@ struct RClass {
struct
iv_tbl
*
iv
;
struct
kh_mt
*
mt
;
struct
RClass
*
super
;
struct
RClass
*
origin
;
};
#define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v)))
...
...
This diff is collapsed.
Click to expand it.
src/class.c
View file @
f962890a
...
...
@@ -194,6 +194,7 @@ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *
if
(
mrb_const_defined_at
(
mrb
,
mrb_obj_value
(
outer
),
name
))
{
c
=
class_from_sym
(
mrb
,
outer
,
name
);
c
=
c
->
origin
;
if
(
super
&&
mrb_class_real
(
c
->
super
)
!=
super
)
{
mrb_raisef
(
mrb
,
E_TYPE_ERROR
,
"superclass mismatch for Class %S (%S not %S)"
,
mrb_sym2str
(
mrb
,
name
),
...
...
@@ -763,12 +764,13 @@ boot_defclass(mrb_state *mrb, struct RClass *super)
else
{
c
->
super
=
mrb
->
object_class
;
}
c
->
origin
=
c
;
c
->
mt
=
kh_init
(
mt
,
mrb
);
return
c
;
}
MRB_API
void
mrb_include_module
(
mrb_state
*
mrb
,
struct
RClass
*
c
,
struct
RClass
*
m
)
MRB_API
inline
void
include_module_at
(
mrb_state
*
mrb
,
struct
RClass
*
c
,
struct
RClass
*
m
,
int
search_super
)
{
struct
RClass
*
ins_pos
;
...
...
@@ -782,6 +784,7 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
}
while
(
p
)
{
if
(
c
!=
p
&&
p
->
tt
==
MRB_TT_CLASS
)
{
if
(
!
search_super
)
break
;
superclass_seen
=
1
;
}
else
if
(
p
->
mt
==
m
->
mt
)
{
...
...
@@ -810,6 +813,63 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
}
}
MRB_API
void
mrb_include_module
(
mrb_state
*
mrb
,
struct
RClass
*
c
,
struct
RClass
*
m
)
{
include_module_at
(
mrb
,
c
,
m
,
FALSE
);
}
MRB_API
void
mrb_prepend_module
(
mrb_state
*
mrb
,
struct
RClass
*
c
,
struct
RClass
*
m
)
{
struct
RClass
*
origin
;
int
changed
=
0
;
origin
=
c
->
origin
;
if
(
origin
==
c
)
{
origin
=
(
struct
RClass
*
)
mrb_obj_alloc
(
mrb
,
MRB_TT_ICLASS
,
c
);
//OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */
origin
->
super
=
c
->
super
;
c
->
super
=
origin
;
c
->
origin
=
origin
;
origin
->
mt
=
c
->
mt
;
c
->
mt
=
kh_init
(
mt
,
mrb
);
}
include_module_at
(
mrb
,
c
,
m
,
FALSE
);
// changed =
if
(
changed
)
{
//rb_vm_check_redefinition_by_prepend(klass);
}
}
static
mrb_value
mrb_mod_prepend_features
(
mrb_state
*
mrb
,
mrb_value
mod
)
{
mrb_value
klass
;
mrb_check_type
(
mrb
,
mod
,
MRB_TT_MODULE
);
mrb_get_args
(
mrb
,
"C"
,
&
klass
);
mrb_prepend_module
(
mrb
,
mrb_class_ptr
(
klass
),
mrb_class_ptr
(
mod
));
return
mod
;
}
static
mrb_value
mrb_mod_prepend
(
mrb_state
*
mrb
,
mrb_value
klass
)
{
mrb_value
*
argv
;
mrb_int
argc
,
i
;
mrb_get_args
(
mrb
,
"*"
,
&
argv
,
&
argc
);
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
mrb_check_type
(
mrb
,
argv
[
i
],
MRB_TT_MODULE
);
}
while
(
argc
--
)
{
mrb_funcall
(
mrb
,
argv
[
argc
],
"prepend_features"
,
1
,
klass
);
mrb_funcall
(
mrb
,
argv
[
argc
],
"prepended"
,
1
,
klass
);
}
return
klass
;
}
static
mrb_value
mrb_mod_append_features
(
mrb_state
*
mrb
,
mrb_value
mod
)
{
...
...
@@ -2090,6 +2150,9 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method
(
mrb
,
mod
,
"class_variable_set"
,
mrb_mod_cvar_set
,
MRB_ARGS_REQ
(
2
));
/* 15.2.2.4.18 */
mrb_define_method
(
mrb
,
mod
,
"extend_object"
,
mrb_mod_extend_object
,
MRB_ARGS_REQ
(
1
));
/* 15.2.2.4.25 */
mrb_define_method
(
mrb
,
mod
,
"extended"
,
mrb_bob_init
,
MRB_ARGS_REQ
(
1
));
/* 15.2.2.4.26 */
mrb_define_method
(
mrb
,
mod
,
"prepend"
,
mrb_mod_prepend
,
MRB_ARGS_ANY
());
mrb_define_method
(
mrb
,
mod
,
"prepended"
,
mrb_bob_init
,
MRB_ARGS_REQ
(
1
));
mrb_define_method
(
mrb
,
mod
,
"prepend_features"
,
mrb_mod_prepend_features
,
MRB_ARGS_REQ
(
1
));
mrb_define_method
(
mrb
,
mod
,
"include"
,
mrb_mod_include
,
MRB_ARGS_ANY
());
/* 15.2.2.4.27 */
mrb_define_method
(
mrb
,
mod
,
"include?"
,
mrb_mod_include_p
,
MRB_ARGS_REQ
(
1
));
/* 15.2.2.4.28 */
mrb_define_method
(
mrb
,
mod
,
"append_features"
,
mrb_mod_append_features
,
MRB_ARGS_REQ
(
1
));
/* 15.2.2.4.10 */
...
...
This diff is collapsed.
Click to expand it.
test/t/module.rb
View file @
f962890a
...
...
@@ -474,6 +474,39 @@ end
# Not ISO specified
assert
(
'Module#prepend'
)
do
module
M0
def
m1
;
[
:M0
]
end
end
module
M1
def
m1
;
[
:M1
,
super
,
:M1
]
end
end
module
M2
def
m1
;
[
:M2
,
super
,
:M2
]
end
end
M3
=
Module
.
new
do
def
m1
;
[
:M3
,
super
,
:M3
]
end
end
module
M4
def
m1
;
[
:M4
,
super
,
:M4
]
end
end
class
C0
include
M0
prepend
M1
def
m1
;
[
:C0
,
super
,
:C0
]
end
end
class
C1
<
C0
prepend
M2
,
M3
include
M4
def
m1
;
[
:C1
,
super
,
:C1
]
end
end
obj
=
C1
.
new
expected
=
[
:M2
,[
:M3
,[
:C1
,[
:M4
,[
:M1
,[
:C0
,[
:M0
],
:C0
],
:M1
],
:M4
],
:C1
],
:M3
],
:M2
]
assert_equal
(
expected
,
obj
.
m1
)
end
assert
(
'Module#to_s'
)
do
module
Test4to_sModules
end
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment