Ruby: 如何创建一个公共静态方法?

在 Java 中,我可能会这样做:

public static void doSomething();

然后我就可以静态地访问这个方法,而不需要创建一个实例:

className.doSomething();

这是我的类,根据我的理解,self.使得这个方法是静态的:

class Ask


def self.make_permalink(phrase)
phrase.strip.downcase.gsub! /\ +/, '-'
end


end

但是当我试着打电话的时候:

Ask.make_permalink("make a slug out of this line")

我得到了:

undefined method `make_permalink' for Ask:Class

如果我没有声明方法是私有的,为什么会这样?

81889 次浏览

Here's my copy/paste of your code into IRB. Seems to work fine.

$ irb
1.8.7 :001 > class Ask
1.8.7 :002?>
1.8.7 :003 >   def self.make_permalink(phrase)
1.8.7 :004?>     phrase.strip.downcase.gsub! /\ +/, '-'
1.8.7 :005?>   end
1.8.7 :006?>
1.8.7 :007 > end
=> nil
1.8.7 :008 > Ask.make_permalink("make a slug out of this line")
=> "make-a-slug-out-of-this-line"

Seems to work. Test it out in your irb as well, and see what results you're getting. I'm using 1.8.7 in this example, but I also tried it in a Ruby 1.9.3 session and it worked identically.

Are you using MRI as your Ruby implementation (not that I think that should make a difference in this case)?

In irb make a call to Ask.public_methods and make sure your method name is in the list. For example:

1.8.7 :008 > Ask.public_methods
=> [:make_permalink, :allocate, :new, :superclass, :freeze, :===,
...etc, etc.]

Since you also marked this as a ruby-on-rails question, if you want to troubleshoot the actual model in your app, you can of course use the rails console: (bundle exec rails c) and verify the publicness of the method in question.

Your given example is working very well

class Ask
def self.make_permalink(phrase)
phrase.strip.downcase.gsub! /\ +/, '-'
end
end


Ask.make_permalink("make a slug out of this line")

I tried in 1.8.7 and also in 1.9.3 Do you have a typo in you original script?

All the best

I am using ruby 1.9.3 and the program is running smoothly in my irb as well.

1.9.3-p286 :001 > class Ask
1.9.3-p286 :002?>     def self.make_permalink(phrase)
1.9.3-p286 :003?>         phrase.strip.downcase.gsub! /\ +/, '-'
1.9.3-p286 :004?>       end
1.9.3-p286 :005?>   end
=> nil
1.9.3-p286 :006 > Ask.make_permalink("make a slug out of this line")
=> "make-a-slug-out-of-this-line"

It's also working in my test script. Nothing wrong with your given code.It's fine.

There is one more syntax which is has the benefit that you can add more static methods

class TestClass


# all methods in this block are static
class << self
def first_method
# body omitted
end


def second_method_etc
# body omitted
end
end


# more typing because of the self. but much clear that the method is static
def self.first_method
# body omitted
end


def self.second_method_etc
# body omitted
end
end