Doubt on define_method in module

Hi

The following code prints "wow" both the times instead of "cool" and "wow" as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module that returns self.class.name.downcase, but I wish to do it this way using define_method.

I don't wish to evaluate the class' name every time the method is called. I want to define the method dynamically when the module is included so that depending on the class, the method is defined dynamically with the return value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Because you're defining the method (twice) on Ex, not on klass.

If you run ruby with -w it will even warn you of the redefined method.

Cheers

···

On 3 December 2017 at 19:50, abhinav ramesh <abhinavramesh@hotmail.com> wrote:

Hi

The following code prints "wow" both the times instead of "cool" and "wow"
as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module
that returns self.class.name.downcase, but I wish to do it this way using
define_method.

I don't wish to evaluate the class' name every time the method is called. I
want to define the method dynamically when the module is included so that
depending on the class, the method is defined dynamically with the return
value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

You can overcome the problem that Matthew points out by specifically defining against the including class using `class_eval`

module Ex
  def self.included(klass)
    klass.class_eval do
      define_method("class_name") do
        klass.name.downcase
      end
    end
  end
end

-Rob

···

On 2017-Dec-4, at 06:54 , Matthew Kerwin <matthew@kerwin.net.au> wrote:

Because you're defining the method (twice) on Ex, not on klass.

If you run ruby with -w it will even warn you of the redefined method.

Cheers

On 3 December 2017 at 19:50, abhinav ramesh <abhinavramesh@hotmail.com> wrote:

Hi

The following code prints "wow" both the times instead of "cool" and "wow"
as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module
that returns self.class.name.downcase, but I wish to do it this way using
define_method.

I don't wish to evaluate the class' name every time the method is called. I
want to define the method dynamically when the module is included so that
depending on the class, the method is defined dynamically with the return
value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
Matthew Kerwin
http://matthew.kerwin.net.au/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hi,

The second time taht you include the module Ex, the "class_name" implementation is overrided. You need to define methods with different names:

module Ex
def self.included(klass)
klass_name = klass.name.downcase
define_method("#{klass_name}_class_name") do
klass_name
end
end
end

class Cool
include Ex
end

class Wow
include Ex
end

puts Cool.new.cool_class_name
puts Wow.new.wow_class_name

Regards,
Danilo Barion Nogueira.

···

________________________________
From: ruby-talk <ruby-talk-bounces@ruby-lang.org> on behalf of abhinav ramesh <abhinavramesh@hotmail.com>
Sent: Sunday, December 3, 2017 7:50 AM
To: ruby-talk@ruby-lang.org
Subject: Doubt on define_method in module

Hi

The following code prints "wow" both the times instead of "cool" and "wow" as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module that returns self.class.name.downcase, but I wish to do it this way using define_method.

I don't wish to evaluate the class' name every time the method is called. I want to define the method dynamically when the module is included so that depending on the class, the method is defined dynamically with the return value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

I understand now.

Thank you.

···

________________________________
From: ruby-talk <ruby-talk-bounces@ruby-lang.org> on behalf of Danilo Nogueira <danilo.barion1986@live.com>
Sent: Monday, December 4, 2017 11:54 AM
To: Ruby users
Subject: Re: Doubt on define_method in module

Hi,

The second time taht you include the module Ex, the "class_name" implementation is overrided. You need to define methods with different names:

module Ex
def self.included(klass)
klass_name = klass.name.downcase
define_method("#{klass_name}_class_name") do
klass_name
end
end
end

class Cool
include Ex
end

class Wow
include Ex
end

puts Cool.new.cool_class_name
puts Wow.new.wow_class_name

Regards,
Danilo Barion Nogueira.

________________________________
From: ruby-talk <ruby-talk-bounces@ruby-lang.org> on behalf of abhinav ramesh <abhinavramesh@hotmail.com>
Sent: Sunday, December 3, 2017 7:50 AM
To: ruby-talk@ruby-lang.org
Subject: Doubt on define_method in module

Hi

The following code prints "wow" both the times instead of "cool" and "wow" as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module that returns self.class.name.downcase, but I wish to do it this way using define_method.

I don't wish to evaluate the class' name every time the method is called. I want to define the method dynamically when the module is included so that depending on the class, the method is defined dynamically with the return value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Thanks a lot.

I understand now

···

________________________________
From: ruby-talk <ruby-talk-bounces@ruby-lang.org> on behalf of Matthew Kerwin <matthew@kerwin.net.au>
Sent: Monday, December 4, 2017 11:54 AM
To: Ruby users
Subject: Re: Doubt on define_method in module

Because you're defining the method (twice) on Ex, not on klass.

If you run ruby with -w it will even warn you of the redefined method.

Cheers

On 3 December 2017 at 19:50, abhinav ramesh <abhinavramesh@hotmail.com> wrote:

Hi

The following code prints "wow" both the times instead of "cool" and "wow"
as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module
that returns self.class.name.downcase, but I wish to do it this way using
define_method.

I don't wish to evaluate the class' name every time the method is called. I
want to define the method dynamically when the module is included so that
depending on the class, the method is defined dynamically with the return
value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Thank you Mr. Rob.

I did just that and it worked perfectly.

···

________________________________
From: ruby-talk <ruby-talk-bounces@ruby-lang.org> on behalf of Rob Biedenharn <rob.biedenharn@gmail.com>
Sent: Monday, December 4, 2017 6:27 PM
To: Ruby users
Subject: Re: Doubt on define_method in module

You can overcome the problem that Matthew points out by specifically defining against the including class using `class_eval`

module Ex
  def self.included(klass)
    klass.class_eval do
      define_method("class_name") do
        klass.name.downcase
      end
    end
  end
end

-Rob

On 2017-Dec-4, at 06:54 , Matthew Kerwin <matthew@kerwin.net.au> wrote:

Because you're defining the method (twice) on Ex, not on klass.

If you run ruby with -w it will even warn you of the redefined method.

Cheers

On 3 December 2017 at 19:50, abhinav ramesh <abhinavramesh@hotmail.com> wrote:

Hi

The following code prints "wow" both the times instead of "cool" and "wow"
as I was expecting. Why does this happen and how should I correct this ?

I know that it is possible to just define an instance method in the module
that returns self.class.name.downcase, but I wish to do it this way using
define_method.

I don't wish to evaluate the class' name every time the method is called. I
want to define the method dynamically when the module is included so that
depending on the class, the method is defined dynamically with the return
value of the method equal to the class' name in lowercase.

module Ex

def self.included(klass)

define_method("class_name") do

klass.name.downcase

end

end

end

class Cool

include Ex

end

class Wow

include Ex

end

puts Cool.new.class_name

puts Wow.new.class_name

# prints wow twice

Regards
Abhinav Ramesh

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
Matthew Kerwin
http://matthew.kerwin.net.au/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;