aboutsummaryrefslogtreecommitdiffstats
path: root/proc.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2022-03-09 14:57:49 -0800
committerJeremy Evans <code@jeremyevans.net>2022-03-29 12:10:13 -0700
commit173a6b6a802d80b8cf200308fd3653832b700b1c (patch)
tree259a61999a721d865b899a329cbfa678a32dade8 /proc.c
parentf3b58e1d38dff2fe69c3f5f858a18fd1b4b936eb (diff)
downloadruby-173a6b6a802d80b8cf200308fd3653832b700b1c.tar.gz
Make define_singleton_method always define a public method
In very unlikely cases, it could previously define a non-public method starting in Ruby 2.1. Fixes [Bug #18561]
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c108
1 files changed, 58 insertions, 50 deletions
diff --git a/proc.c b/proc.c
index 93b4013c31..4f43c56006 100644
--- a/proc.c
+++ b/proc.c
@@ -2165,61 +2165,14 @@ rb_mod_public_instance_method(VALUE mod, VALUE vid)
return mnew_unbound(mod, id, rb_cUnboundMethod, TRUE);
}
-/*
- * call-seq:
- * define_method(symbol, method) -> symbol
- * define_method(symbol) { block } -> symbol
- *
- * Defines an instance method in the receiver. The _method_
- * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
- * If a block is specified, it is used as the method body.
- * If a block or the _method_ parameter has parameters,
- * they're used as method parameters.
- * This block is evaluated using #instance_eval.
- *
- * class A
- * def fred
- * puts "In Fred"
- * end
- * def create_method(name, &block)
- * self.class.define_method(name, &block)
- * end
- * define_method(:wilma) { puts "Charge it!" }
- * define_method(:flint) {|name| puts "I'm #{name}!"}
- * end
- * class B < A
- * define_method(:barney, instance_method(:fred))
- * end
- * a = B.new
- * a.barney
- * a.wilma
- * a.flint('Dino')
- * a.create_method(:betty) { p self }
- * a.betty
- *
- * <em>produces:</em>
- *
- * In Fred
- * Charge it!
- * I'm Dino!
- * #<B:0x401b39e8>
- */
-
static VALUE
-rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
+rb_mod_define_method_with_visibility(int argc, VALUE *argv, VALUE mod, const struct rb_scope_visi_struct* scope_visi)
{
ID id;
VALUE body;
VALUE name;
- const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);
- const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE};
- const rb_scope_visibility_t *scope_visi = &default_scope_visi;
int is_method = FALSE;
- if (cref) {
- scope_visi = CREF_SCOPE_VISI(cref);
- }
-
rb_check_arity(argc, 1, 2);
name = argv[0];
id = rb_check_id(&name);
@@ -2282,10 +2235,64 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
/*
* call-seq:
+ * define_method(symbol, method) -> symbol
+ * define_method(symbol) { block } -> symbol
+ *
+ * Defines an instance method in the receiver. The _method_
+ * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
+ * If a block is specified, it is used as the method body.
+ * If a block or the _method_ parameter has parameters,
+ * they're used as method parameters.
+ * This block is evaluated using #instance_eval.
+ *
+ * class A
+ * def fred
+ * puts "In Fred"
+ * end
+ * def create_method(name, &block)
+ * self.class.define_method(name, &block)
+ * end
+ * define_method(:wilma) { puts "Charge it!" }
+ * define_method(:flint) {|name| puts "I'm #{name}!"}
+ * end
+ * class B < A
+ * define_method(:barney, instance_method(:fred))
+ * end
+ * a = B.new
+ * a.barney
+ * a.wilma
+ * a.flint('Dino')
+ * a.create_method(:betty) { p self }
+ * a.betty
+ *
+ * <em>produces:</em>
+ *
+ * In Fred
+ * Charge it!
+ * I'm Dino!
+ * #<B:0x401b39e8>
+ */
+
+static VALUE
+rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
+{
+ const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);
+ const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE};
+ const rb_scope_visibility_t *scope_visi = &default_scope_visi;
+
+ if (cref) {
+ scope_visi = CREF_SCOPE_VISI(cref);
+ }
+
+ return rb_mod_define_method_with_visibility(argc, argv, mod, scope_visi);
+}
+
+/*
+ * call-seq:
* define_singleton_method(symbol, method) -> symbol
* define_singleton_method(symbol) { block } -> symbol
*
- * Defines a singleton method in the receiver. The _method_
+ * Defines a public singleton method in the receiver. The _method_
* parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
* If a block is specified, it is used as the method body.
* If a block or a method has parameters, they're used as method parameters.
@@ -2315,8 +2322,9 @@ static VALUE
rb_obj_define_method(int argc, VALUE *argv, VALUE obj)
{
VALUE klass = rb_singleton_class(obj);
+ const rb_scope_visibility_t scope_visi = {METHOD_VISI_PUBLIC, FALSE};
- return rb_mod_define_method(argc, argv, klass);
+ return rb_mod_define_method_with_visibility(argc, argv, klass, &scope_visi);
}
/*