@@ -83,6 +83,7 @@ static VALUE rb_cFalseClass_to_s;
8383#define id_init_dup idInitialize_dup
8484#define id_const_missing idConst_missing
8585#define id_to_f idTo_f
86+ static ID id_instance_variables_to_inspect ;
8687
8788#define CLASS_OR_MODULE_P (obj ) \
8889 (!SPECIAL_CONST_P(obj) && \
@@ -733,11 +734,17 @@ rb_inspect(VALUE obj)
733734static int
734735inspect_i (ID id , VALUE value , st_data_t a )
735736{
736- VALUE str = (VALUE ) a ;
737+ VALUE * args = (VALUE * ) a , str = args [ 0 ], ivars = args [ 1 ] ;
737738
738739 /* need not to show internal data */
739740 if (CLASS_OF (value ) == 0 ) return ST_CONTINUE ;
740741 if (!rb_is_instance_id (id )) return ST_CONTINUE ;
742+ if (!NIL_P (ivars )) {
743+ VALUE name = ID2SYM (id );
744+ for (long i = 0 ; RARRAY_AREF (ivars , i ) != name ; ) {
745+ if (++ i >= RARRAY_LEN (ivars )) return ST_CONTINUE ;
746+ }
747+ }
741748 if (RSTRING_PTR (str )[0 ] == '-' ) { /* first element */
742749 RSTRING_PTR (str )[0 ] = '#' ;
743750 rb_str_cat2 (str , " " );
@@ -752,13 +759,15 @@ inspect_i(ID id, VALUE value, st_data_t a)
752759}
753760
754761static VALUE
755- inspect_obj (VALUE obj , VALUE str , int recur )
762+ inspect_obj (VALUE obj , VALUE a , int recur )
756763{
764+ VALUE * args = (VALUE * )a , str = args [0 ];
765+
757766 if (recur ) {
758767 rb_str_cat2 (str , " ..." );
759768 }
760769 else {
761- rb_ivar_foreach (obj , inspect_i , str );
770+ rb_ivar_foreach (obj , inspect_i , a );
762771 }
763772 rb_str_cat2 (str , ">" );
764773 RSTRING_PTR (str )[0 ] = '#' ;
@@ -791,17 +800,47 @@ inspect_obj(VALUE obj, VALUE str, int recur)
791800 * end
792801 * end
793802 * Bar.new.inspect #=> "#<Bar:0x0300c868 @bar=1>"
803+ *
804+ * If _obj_ responds to +instance_variables_to_inspect+, then only
805+ * the instance variables listed in the returned array will be included
806+ * in the inspect string.
807+ *
808+ *
809+ * class DatabaseConfig
810+ * def initialize(host, user, password)
811+ * @host = host
812+ * @user = user
813+ * @password = password
814+ * end
815+ *
816+ * private
817+ * def instance_variables_to_inspect = [:@host, :@user]
818+ * end
819+ *
820+ * conf = DatabaseConfig.new("localhost", "root", "hunter2")
821+ * conf.inspect #=> #<DatabaseConfig:0x0000000104def350 @host="localhost", @user="root">
794822 */
795823
796824static VALUE
797825rb_obj_inspect (VALUE obj )
798826{
799- if (rb_ivar_count (obj ) > 0 ) {
800- VALUE str ;
827+ VALUE ivars = rb_check_funcall (obj , id_instance_variables_to_inspect , 0 , 0 );
828+ st_index_t n = 0 ;
829+ if (UNDEF_P (ivars )) {
830+ n = rb_ivar_count (obj );
831+ ivars = Qnil ;
832+ }
833+ else if (!NIL_P (ivars )) {
834+ Check_Type (ivars , T_ARRAY );
835+ n = RARRAY_LEN (ivars );
836+ }
837+ if (n > 0 ) {
801838 VALUE c = rb_class_name (CLASS_OF (obj ));
802-
803- str = rb_sprintf ("-<%" PRIsVALUE ":%p" , c , (void * )obj );
804- return rb_exec_recursive (inspect_obj , obj , str );
839+ VALUE args [2 ] = {
840+ rb_sprintf ("-<%" PRIsVALUE ":%p" , c , (void * )obj ),
841+ ivars
842+ };
843+ return rb_exec_recursive (inspect_obj , obj , (VALUE )args );
805844 }
806845 else {
807846 return rb_any_to_s (obj );
@@ -4600,6 +4639,7 @@ void
46004639Init_Object (void )
46014640{
46024641 id_dig = rb_intern_const ("dig" );
4642+ id_instance_variables_to_inspect = rb_intern_const ("instance_variables_to_inspect" );
46034643 InitVM (Object );
46044644}
46054645
0 commit comments