What Does a Java Static Method Look Like in Ruby

Java's static vs Ruby's self

No. Java's static and Ruby's self have absolutely nothing whatsoever to do with each other.

The Java equivalent to Ruby's self is this. The Ruby equivalent to Java's static does not exist.

Java's static means that the method is dispatched statically instead of dynamically. In Ruby, methods are always dispatched dynamically. static means that the method is not called on any object. In Ruby, methods are always called on objects. Since static methods in Java aren't associated with any object, they don't have access to any object state. In Ruby, methods always have access to the state of their associated instance.

In short, static methods aren't really methods at all, they are procedures. Ruby doesn't have procedures, it only has (instance) methods.

There is no construct in Ruby that would even be remotely equivalent to Java's static.

Ruby: How to make a public static method?

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

Are Ruby class variables similar to the Java static variables?

There's a lot of similarity between Ruby and Java by virtue of them being object-oriented, but their family tree is different. Ruby leans very heavily on Smalltalk while Java inherits from the C++ school of thinking.

The difference here is that Ruby's concept of public/private/protected is a lot weaker, they're more suggestions than rules, and things like static methods or constants are more of a pattern than a construct in the language.

Global variables are frowned on quite heavily, they can cause chaos if used liberally. The Ruby way is to namespace things:

$ugly_global = 0  # Not recommended, could conflict with other code
# Ownership of this variable isn't made clear.

$ugly_global += 1 # Works, but again, it's without context.

module UglyCounter # Defines a module/namespace to live in
def self.current # Defines a clear interface to this value
@counter ||= 0 # Initializes a local instance variable
end

def self.current=(v) # Allow modification of this value
@counter = v.to_i # A chance to perform any casting/cleaning
end
end

UglyCounter.current += 1 # Modifies the state of a variable, but
# the context is made clear.

Even a thin layer like this module gives you the ability to intercept read/write operations from this variable and alter the behaviour. Maybe you want to default to a particular value or convert values into a normalized form. With a bare global you have to repeat this code everywhere. Here you can consolidate it.

Class variables are a whole different thing. They're also best avoided because sharing data between the class and instances of this class can be messy. They're two different contexts and that separation should be respected.

class MessyClass
@@shared = 0

def counter
@@shared
end

def counter=(v)
@@shared = v
end
end

This is a pretty rough take on how to use a shared class-level instance variable. The problem here is each instance is directly modifying it, bypassing the class context, which means the class is helpless. This is fundamentally rude, the instance is over-extending its authority. A better approach is this:

class CleanerClass
def self.counter
@counter ||= 0
end

def self.counter=(v)
@counter = v.to_i
end

# These are reduced to simple bridge methods, nothing more. Because
# they simply forward calls there's no breach of authority.
def counter
self.class.counter
end

def counter=(v)
self.class.counter = v
end
end

In many languages a static class method becomes available in the scope of an instance automatically, but this is not the case in Ruby. You must write bridge/proxy/delegate methods, the terminology here varying depending on what you're used to.

Ruby on rails - Static method

To declare a static method, write ...

def self.checkPings
# A static method
end

... or ...

class Myclass extend self

def checkPings
# Its static method
end

end

Is it possible to see via which child class was a parent's static method called in Java?

You cannot override static methods in Java, so any calls to the static method via a subclass will be bound to the base class at compile time. Thus a call to B.testMethod() will be bound to A.testMethod before the application is ever run.

Since you are looking for the information at runtime, it will not be available through normal Java operations.

Convert sample java code to ruby to understand static variales in ruby

Use @@ to assign a class variable that is shared with all instances of that class:

class A
@@cached_names = nil

def self.get_names
@@cached_names = prepare_names if !@@cached_names
@@cached_names
end
end

The keyword self means assign the method to be a class method (analogous to a static method in Java). Without the self keyword, the method becomes an instance method.

Here's a nice summary of class and instance methods:

Ruby class with static method calling a private method?

First off, static is not really part of the Ruby jargon.

Let's take a simple example:

class Bar
def self.foo
end
end

It defines the method foo on an explicit object, self, which in that scope returns the containing class Bar.
Yes, it can be defined a class method, but static does not really make sense in Ruby.

Then private would not work, because defining a method on an explicit object (e.g. def self.foo) bypasses the access qualifiers and makes the method public.

What you can do, is to use the class << self syntax to open the metaclass of the containing class, and define the methods there as instance methods:

class Foo
class << self

def bar
do_calc
end

def baz
do_calc
end

private

def do_calc
puts "calculating..."
end
end
end

This will give you what you need:

Foo.bar
calculating...

Foo.baz
calculating...

Foo.do_calc
NoMethodError: private method `do_calc' called for Foo:Class

Has Crystal got static methods?

The correct syntax for class methods is def self.test, not self.def test. Class methods are called using Test.test, not Test::test.

Ruby: Alter class static method in a code block

You might want to take a look at a Ruby mocking framework like Mocha, but in terms of using plain Ruby it can be done using alias_method (documentation here) e.g.

beforehand:

class Thread
class << self
alias_method :old_current, :current
end
end

then define your new method

class Thread
def self.current
# implementation here
end
end

then afterwards restore the old method:

class Thread
class << self
alias_method :current, :old_current
end
end

Update to illustrate doing this from within a test

If you want to do this from within a test you could define some helper methods as follows:

def replace_class_method(cls, meth, new_impl)
cls.class_eval("class << self; alias_method :old_#{meth}, :#{meth}; end")
cls.class_eval(new_impl)
end

def restore_class_method(cls, meth)
cls.class_eval("class << self; alias_method :#{meth}, :old_#{meth}; end")
end

replace_class_method is expecting a class constant, the name of a class method and the new method definition as a string. restore_class_method takes the class and the method name and then aliases the original method back in place.

Your test would then be along the lines of:

def test
new_impl = <<EOM
def self.current
"replaced!"
end
EOM
replace_class_method(Thread, 'current', s)
puts "Replaced method call: #{Thread.current}"
restore_class_method(Thread, 'current')
puts "Restored method call: #{Thread.current}"
end

You could also write a little wrapper method which would replace a method, yield to a block and then ensure that the original method was reinstated afterwards e.g.

def with_replaced_method(cls, meth, new_impl)
replace_class_method(cls, meth, new_impl)
begin
result = yield
ensure
restore_class_method(cls, meth)
end
return result
end

Inside your test method this could then be used as:

with_replaced_method(Thread, 'current', new_impl) do
# test code using the replaced method goes here
end
# after this point the original method definition is restored

As mentioned in the original answer, you can probably find a framework to do this for you but hopefully the above code is interesting and useful anyway.



Related Topics



Leave a reply



Submit