I'm trying to create an actor, using the newest Akka version (2.3.2 right now) using JRuby. Problem is, I keep getting the error:
Java::JavaLang::IllegalArgumentException: erased Creator types are unsupported, use Props.create(actorClass, creator) instead
Basically, I'm following the code here on Akka Documentation
I cannot create a akka.japi.Creator, because this requires Generic information, and these are erased at run-time (and JRuby is basically a run-time-everywhere). What I already tried:
class GreetingActor < UntypedActor
def onReceive(message)
if (message.is_a? Greeting)
puts("Hello " + message.who)
end
end
end
system = ActorSystem.create("MySystem")
greeter = system.actorOf(Props.create(GreetingActor))
The last line fails with erased Creator types are unsupported. I tried to wrap it under a akka.japi.Creator, but with the same error (as Creator needs generics information, and JRuby doesn't provide it). I've tried to use "become_java!" on GreetingActor, but it returns nil (JRuby can't create new java classes from Ruby classes if the Ruby class extends from a Java class).
Is there a way to declare the Creator passing generics information?
I was trying to do the same thing and while I don't have an answer to the title's question I do have an answer for getting the example working. You have to use a different means of constructing the Props instance.
You need to use a factory:
java_import 'akka.actor.UntypedActorFactory'
class GreetingActorFactory
include UntypedActorFactory
def create
GreetingActor.new
end
end
Then you can use it as follows:
system = ActorSystem.create("GreetingSystem")
props = Props.create(GreetingActorFactory.new)
greeter = system.actorOf(props, "greeter")
greeter.tell(Greeting.new("John Weathers"), nil)
Hopefully, this helps you get further along!
I've already solved the Akka problem using the following gist: https://gist.github.com/mauricioszabo/6a713fd416c512e49f70
Still, the JRuby implementation may fail on other libraries that depends on not-erased types, but for now, I can work around in Akka using the code above.
Related
I am trying to create some data driven API tests using Test::Unit for ruby. The eventual intention is to read a series of test cases in from a .csv file. In looking for something that would be the equivalent of #dataprovider for testng, I found a class called Data which looks like exactly what I need.
http://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/Data/ClassMethods
However, when I tried to create a test case to try to get it working, I get an error saying
"initial_test.rb:4:in <class:InitialTest>': undefined methoddata' for InitialTest:Class (NoMethodError)
"
code I was running:
require "test/unit"
class InitialTest < Test::Unit::TestCase
data("true" => [true],
"false" => [false])
def test_true_is_true(data)
value = data
assert(false, "FAIL!")
end
end
I can't seem to find any mention of the Data class outside of the documentation. Has anyone used this class? Am I missing something?
I'm not familiar with this module in particular, but since data is defined as an instance method on Test::Unit::Data and Test::Unit::Data is a Module, this works:
class YourTest < Test::Unit::TestCase
include Test::Unit::Data
data(…)
end
This said, you're going to want to take a closer look at the docs you linked since your example usage is looking like copy-pasta.
Turns out that the problem was that I was using an older version of Ruby that did not include the class I was trying to use. Updating to a newer version solved the problem.
I'm learning how to use Module.prepend instead of alias_method_chain in my Ruby code, and I've noticed that some people use send to call it (example):
ActionView::TemplateRenderer.send(:prepend,
ActionViewTemplateRendererWithCurrentTemplate)
While others call it directly (example):
ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate)
And, although I haven't seen anyone use this style, I suspect from the documentation that you could even write this in the module you're prepending from:
module ActionViewTemplateRendererWithCurrentTemplate
# Methods you're overriding go here
prepend_features ActionView::TemplateRenderer
end
Is there some difference between these three styles? Is there a reason to favor one over the others?
Module#prepend was added to Ruby version 2.0.0.
It was originally added as a private method, with the intended use case being in the following format:
module Foo
# ...
end
class Bar
prepend Foo
# ... The rest of the class definition ...
end
However, it soon became apparent that in many cases people wanted to prepend a module to a class without defining any other aspects of the class (in that section of code). Hence, the following pattern became common:
Bar.send(:prepend, Foo)
In Ruby version 2.1.0, this issue was addressed by making Module#prepend a public method - so you can now simply write this as:
Bar.prepend(Foo)
However, note that if you are writing a library that is required to support Ruby 2.0.0 (even though official support ended on 24th Feb 2016), then you must unfortunately stick to the old .send(:prepend, ...) approach.
Module#include (which has been in the Ruby language since its inception) was also a private method in version <= 2.0.0, and was made public in 2.1.0.
I've written a small method to query and retrieve from an MS SQL 2008 server and I am not sure where to put the code in my rails app.
The scenario:
I am writing a Ruby and Rails app with a connection to a legacy MS SQL 2008 server DB.
A lot is working as expected, which is nice.
For now I work off a copy of the legacy DB and I treat it as readonly. It's big (7000+ tables some of which have over 40 million records). I am using it 'as-is' and don't want to change any of the underlying schema.
I do want to extend some very server-specific functionality. For instance, I make use of:
thing = ActiveRecord::Base.connection.exec_query(my_query_string_here)
... and it works. The result is an array that contains a hash and I can get to the relevant hash value by using:
thing[0][""]
... which works.
So, I thought I should write a method to make this easier and I wrote:
Class Tool < ActiveRecord::Base
def self.queryRDW(x)
res=ActiveRecord::Base.connection.exec_query(x)
ret=res.to_hash
return ret[0][""]
end
end
and put it in config/initializers/tool.rb Unfortunately, webrick complains about the file during boot with the following cryptic error:
.../config/initializers/tool.rb:7: syntax error, unexpected keyword_end, expecting $end (SyntaxError)
I recognize that this is not an out-of-the-box rails-way of doing things, so please don't remind me. (My struggles remind me often enough)
My question:
Where should I put this code so that I can invoke it from within a controller or a view in my rails app? Does this need to be a new Class method or something else?
Many thanks!
Addendum:
I changed Class to class (doh!)
I moved tool.rb into lib/
I changed tool.rb to now be:
module Tool
def self.queryRDW(x)
res = ActiveRecord::Base.connection.exec_query(x)
res.to_hash[0][""]
end
end
but doing this in app/views/stats.html.erb
thing=queryRDW("mysql string")
gets me an 'undefined method error'
Addendum 2
I made the directory app/concerns and put tool.rb there.
When I use:
<%=queryRDW("myStringHere")%>
in:
app/views/stats.html.erb
I get:
undefined method `queryRDW' for #<#<Class:0x0000000378ccf8>:0x00000003c1ce58>
You need to lowercase the keyword class in line 1.
I'd also say that this class doesn't need to inherit from ActiveRecord::Base — and doesn't even really need to be a class — if it's simply a wrapper around exec_query. There's nothing "wrong" with this, but if you never intend to instantiate an object of this class, you could just create a simple utility module:
module Tool
def self.queryRDW(x)
res = ActiveRecord::Base.connection.exec_query(x)
res.to_hash[0][""]
end
end
You can save this file in a couple of places:
lib/tool.rb. If you're using Rails 3, you'll need to add (or uncomment) this line in config/application.rb:
# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
app/concerns/tool.rb. This will automatically be detected by Rails 3.
I generally use app/concerns for tools that are entirely application-specific and lib for utilities that I might reuse among several different applications.
I wouldn't put this in config/initializers. This seems like code you'd put in app/models.
The error you're getting is syntax related, so double check the syntax.
To answer your question more directly, though, it's acceptable to put this stuff in your model if it's model related (in other words, part of your business domain). If it is something extraneous or orthogonal to your domain, I'd put it in lib.
Hope this helps.
I have this idea for a client/server archetype where the server would hold a hash of Marshal.dump'ed class objects along with their version numbers. Then the client could query the server concerning the version number and import the newer version of the class before instantiating it:
class Stuff
def methods
gibberish
end
end
$obj_hash["Stuff"] = [3.0, Marshal.dump(Stuff)]
The problem I'm running into is that Ruby doesn't seem to want to allow me to Marshal.load the data once I've downloaded it from the server because the class and its methods don't exist in the client. If I bypass this by creating a 'dummy' class I'm then unable to replace the dummy class with the Marshal.load'ed data. If I simply try to use the loaded data as a class it functions according to the contents of the dummy class rather than the downloaded one.
Is there another way to go about this? If not then I guess I could just gz the code and then eval it at the other end, but I'm trying to avoid using eval or sending easily decipherable code over the line.
Thanks in advance for any advice.
Look at what happens.
class Stuff
def methods
"foo"
end
end
ruby-1.8.7-p352 :001 > Marshal.dump(Stuff)
=> "\004\bc\bStuff"
Notice how it says nothing about "methods" or "foo." If the server isn't sending that code down the wire, how is the client supposed to know what Stuff#methods should do?
It won't. :)
To do what you want to do, you'll have to send down the code itself and eval it. You'll have to implement the versioning logic yourself, of course, and "really re-define" the classes (not just monkey-patch) them.
See are you allowed to redefine a class in ruby? or is this just in irb
I'm trying to wrap my head around Ruby, and one thing I'm struggling with is the lack of interface/abstract class support. From googling about, the response I continuously see to abstract class related Ruby questions is "You're thinking in Java. Ruby doesn't work that way"
So, how would one work in Ruby without interfaces/abstract classes?
For example, in Java I might create an abstract class "book", with subclasses "novel", "textbook", and "journal". There is a lot of common functionality that I throw in 'book', but I don't want it to be directly accessible - a book must be either a novel, textbook or journal.
In ruby, how would I write out that sort of functionality?
I am also Ruby starter. From my understanding, there is a closer rival for abstract classes in ruby. that is module. you can't create any instances of module but you can include with another class. So a target class will get the whole functionality of parent
module Log
def write
//blah
end
end
class EventLog
include Log
def Prepare
end
end
In statically typed languages like java/C# , Interfaces enforce the classes to have all the methods at compile time. Since Ruby is dynamic, there is no meaning in it.
For more clarity, check these posts why dynamic languages don't require interfaces..
why-dont-we-require-interfaces-in-dynamic-languages
why-do-dynamic-languages-like-ruby-and-python-not-have-the-concept-of-interfaces
Cheers
there are ways to implement this type of thing, including abstract_type gem. While ruby doesn't require it and has mixins, i think there are cases, like adapters, where you'd want to secure your interface to a set of objects with something more explicit.
also, check out http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/