Get back variables passed to jruby from java - java

This may be simple , I'll search for this but no luck
I have the code:
import org.jruby.embed.ScriptingContainer;
public class Test {
public static void main(String[] args){
ScriptingContainer container = new ScriptingContainer();
int a = 1234;
container.put("a", a);
container.runScriptlet("a = a+10 ; puts a");
System.out.println(a);
}
}
You can see that ,the output from container.runScriptlet("a = a+10 ; puts a"); is 1244
and System.out.println(a); is 1234
Now i want the a variable must be change after run from jruby ,so that the
System.out.println(a); should be 1244
How to do that ?

Your example can never work as written. int is a primitive type and will be passed by value, not by reference. That is, the value 1234 gets passed to JRuby, not "a". You can easily see this by the fact that you can give the variable a different name in container.put.
If you want just a single variable back, you can return it from your script:
public class Main {
public static void main(String[] args){
ScriptingContainer container = new ScriptingContainer();
container.put("a", 1234);
Object v = container.runScriptlet("a += 10; a");
System.out.println(v);
}
}
If you need more values, I'd recommend creating a simple bean that you can use to pass values back in an organized manner:
public class Main {
public static class Values {
private String name;
private Long age;
public void setName(String n) {
this.name = n;
}
public void setAge(Long a) {
this.age = a;
}
public String toString() {
return name + " is " + age + " years old!";
}
}
public static void main(String[] args){
ScriptingContainer container = new ScriptingContainer();
Values vs = new Values();
container.put("values", vs);
container.runScriptlet("values.age = 20; values.name = 'Tanya'");
System.out.println(vs);
}
}
As a third solution, follow the example in the JRuby Javadocs:
ScriptingContainer container = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
container.runScriptlet("p=9.0");
container.runScriptlet("q = Math.sqrt p");
container.runScriptlet("puts \"square root of #{p} is #{q}\"");
System.out.println("Ruby used values: p = " + container.get("p") +
", q = " + container.get("q"));

Related

Instance variables with arrays

I am trying to create an instance variable that is an array. I have many methods that will produce certain statistics about the array. I'm wondering if someone can explain to me if I am going about this the correct way. I'm rather new to Java, so any pointers is greatly appreciated.
When I run the program I get errors, such like Null. I'm not looking to fix these errors now, I'm just wondering if I am going about this the correct way.
My data class:
import java.util.Arrays;
public class Stat {
private double data[];
public Stat()
{
data = new double[1];
data[0]= 0.0;
}
public Stat(double[] d)
{
d = new double[d.length];
}
public double[] getData()
{
return data;
}
public void setData(double[] d)
{
}
Main method:
double[] data = {1,2,2,3,4,5};
Stat stat1 = new Stat(data);
System.out.println(stat1.getData());
System.out.println("stat1 data = " + stat1.toString());
System.out.println("stat1 min = " + stat1.min());
System.out.println("stat1 max = " + stat1.max());
System.out.println("stat1 average = " + stat1.average());
System.out.println("stat1 mode = " + stat1.mode());
System.out.println("stat1 data = " + stat1.toString());
This constructor doesn't really do anything. You pass in an array in d, and then assign d to a different array when you say new, and additionally, d only lives on the stack until the method returns. Whenever this constructor is used data is never initialized and that's where your error is coming from.
Change:
public Stat(double[] d)
{
d = new double[d.length];
}
to something like this:
public Stat(double[] d)
{
data = d;
}
Here's what I ran on my computer:
public class Stat {
private double data[];
public Stat()
{
data = new double[1];
data[0]= 0.0;
}
public Stat(double[] d)
{
data = d;
}
public double[] getData()
{
return data;
}
}
public class JavaTest {
public static void main(String[] args) {
double[] data = {1,2,2,3,4,5};
Stat stat1 = new Stat(data);
System.out.println(stat1.getData()[0]); //outputs 1.0
}
}
Change the constructor to be
public Stat(double[] d)
{
data = d.clone();
}
Because by using the new keyword, your are creating a new empty array. Second error, you can't print directly an array. You have to print its elements, one by one using a for loop for example.
However, I suggest that you override the toString() method
#Override
public String toString(){
return Arrays.toString(data);
}
Then printing your class will output the content of the array
System.out.println("stat1 data = " + stat1);

trying to reassign value to class instance variables

I am being beginner trying to learn java basics and here in the this program I am confused why
we can't reassign the value of class instance variable.
this is error in this program. Please guys help me out to figure it out. thanks
class AddInsideClassVar{
int a = 3;
int c;
c = a + a;
public static void main(String args[]){
System.out.println();
}
}
You may define fields within a class, but you are not allowed to put calculation statements outside of a method definition. A field declaration is of the form type; or type = value;
For example (from your code);
class AddInsideClassVar{
static int a = 3; // ok this is a declaration for a field (variable)
static int c; // ok, this is too
//c = a + a; // this is a statement and not a declaration. A field may be
// declared only once
static int d = a + a; // this will work since it is part of a declaration.
public static void main(String args[]){
System.out.println("a=" + a + ", c=" + c + ", d=" + d);
}
}
You cannot execute c = a + a in that section. If anything you'd need to do
int a = 3;
int c = a + a;
If you make these variables static then you could do
private static int a = 3;
private static int c;
static {
c = a + a;
}
You can try this (just an example of workaround):
class AddInsideClassVar{
static {
int a = 3;
int c;
c = a + a;
System.out.println(c);
}
public static void main(String args[]){
}
}
You may be mixing your statics with instance variables. Here's how I would write this to not confuse myself:
public class AddInsideClassVar{
int a;
int c;
public void doStuff() {
a = 3;
c = a + a;
}
public static void main(String args[]){
AddInsideClassVar instance = new AddInsideClassVar();
instance.doStuff();
System.out.println(c);
}
}
a and c are instance variables. They are manipulated by a non-static method which requires an instance of the class to operate on. So, I create the instance in main(), then call the function to manipulate instance variables.
Explanation : int c = a + a is a declaration whereas " c = a + a ; " ( alone ) is a statement ; You have a point, it does not make much sense ;
class MyClass {
int a = 3;
int c = a + a; // Correct
}
or
class MyClass {
int a = 3;
int c;
public void addition () {
c = a + a; // Correct
}
}
but not
class MyClass {
int a = 3;
int c;
c = a + a; // Incorrect
}
NOTE : On the other, the Scala programming language ( compiles to JVM ) allows you to do the following :
scala> class MyClass { val a:Int = 3;
var c:Int = _;
c = a + a ; // Correct
}
defined class MyClass

Passing System.out.println(); as an argument in a method

I want to pass System.out.println(); as an argument but the compiler won't allow me to return a void type as an argument. here is what I want it for.
public class Array {
public static void main(String args[]) {
a(data());
}
static void a(e) {
System.out.println(e);
}
static void data() {
...
}
}
So What is want a(data()); to look like after it is compiled is something like this.
a(data()) = System.out.println(data(){...});
Eventually I want to shorthand System.out.println().
What you are doing here is not passing System.out.println() as an argument; you are trying to pass an argument to System.out.println()
Try changing the return type of data() to String, or int, or anything other than void, and return something of that type from it.
Also change the parameter type of e in the function definition of a() to match the return type of data().
After you make these changes, calling a(data()); will actually print something out.
Example:
public static void main(String args[]) {
a(data());
}
// shorthand for System.out.println
static void a(String e) {
System.out.println(e);
}
// a method that returns some data
static String data() {
// replace this with whatever actual data you want to return
return "This is some data...";
}
If you just want to shorthand System.out.println, then have a method with return type void that accepts a string argument and inside of the method just do:
System.out.println(argument)
As mentioned by others, you don't want/need to pass System.out.println as a method argument. However, if you would like to do that (one never knows...), you could do that in Java 8 with Lambda expressions.
Create a functional interface:
#FunctionalInterface
public interface Action {
void run(String param);
}
Passing this interface to a method:
public class MyClass {
public void execute(Action action){
action.run("Hello!");
}
}
Use this class:
MyClass c = new MyClass();
c.execute(System.out::println);
Simply save your println statements to String and return it for printing
Your code:
static void data() {
int array[] = {1,5,6};
int alength = array.length;
System.out.println(" Location\tData");
for(int i=0;i<alength;i++) {
System.out.println(" " + i + "\t\t" + array[i]);
}
}
Change to:
static String data() {
int array[] = {1,5,6};
int alength = array.length;
//Note extra \n symbol for new line
String result = " Location\tData\n";
for(int i=0;i<alength;i++) {
result += " " + i + "\t\t" + array[i] + "\n";
}
return result;
}
then modify your a() method to accept String as a parameter:
static void a(String result) {System.out.println(result);}
A working example could look like this:
public class Array {
public static void main(String args[]) {
println(data());
}
// I strongly advise to use understandable naming
// a() is completely uninformative
static void println(String result) {
System.out.println(result);
}
static String data() {
int array[] = { 1, 5, 6 };
int alength = array.length;
// Note extra \n symbol for new line
String result = " Location\tData\n";
for (int i = 0; i < alength; i++) {
result += " " + i + "\t\t" + array[i] + "\n";
}
return result;
}
}
While the compiler may not allow you to pass a function pointer, it should allow you to pass blocks.
In Objective-C; a block as the following syntax:
void (^action)(NSString *s) = ^(NSString *s){ NSLog(s); }
You can then pass your "action" block around as a parameter, and call it whenever required:
action(#"Hello World");
Blocks are available in all recent variations of C, Wikipedia has a nice article on the subject at http://en.wikipedia.org/wiki/Blocks_(C_language_extension).
I want to change this code
package Array;
import java.util.Random;
public class Array {
public static void main(String args[]) {
data();
a();
random();
a();
array();
a();
rows();
a();
System.out.println("average " + average(45,15,15,48,97,45));
}
static String s() {
return "helloWorld";
}
static void a() {System.out.println();}
static void data() {
int array[] = {1,5,6};
int alength = array.length;
System.out.println(" Location\tData");
for(int i=0;i<alength;i++) {
System.out.println(" " + i + "\t\t" + array[i]);
}
}
static void random() {
Random rdm = new Random();
int freq[] = new int[7];
for(int i=1;i<1000;i++) {
++freq[1+rdm.nextInt(6)];
}
System.out.println("Face\tFrequency");
int frequence = freq.length;
for(int face=1;face<frequence;face++) {
System.out.println(face+"\t"+freq[face]);
}
}
static void array() {
String po[] = {"lala","po","tinkiwinki","disty"};
for(String lala: po) {
System.out.print(lala + " ");
}
System.out.println();
}
static void rows() {
int arrays[][]= {{1,5,78,15},{45,67},{875,15687,158,4515,23,2,2}};
for(int i=0;i<arrays.length;i++) {
for(int j=0;j<arrays[i].length;j++) {
System.out.print(arrays[i][j]+"\t");
}
System.out.println();
}
}
static int average(int...numbers) {
int total=0;
for(int x:numbers)
total += x;
return total/numbers.length;
}
}
class time {
int h, m, s;
void setTime(int hour,int minute,int second) {
h = ((hour>=0 && hour<=24) ? hour : 0);
m = ((minute>=0 && minute<=60) ? minute : 0);
s = ((second>=0 && second<=60) ? second : 0);
}
into this type of code for main.
a(data());
a(random());
a(array());
a(rows());
a("average " + average(45,15,15,48,97,45));

Java - Using the output from one class in another

I'm trying to write a program that takes the output of adding two numbers in one class together and adds it to a different number. Here is the first class:
public class Add{
public static void main(String[] args) {
int a = 5;
int b = 5;
int c = a + b;
System.out.println(c);
}
}
And the second:
public class AddExtra{
public static void main(String[] args) {
Add a = new Add();
int b = 5;
int c = a.value+b;
System.out.println(c);
}
}
How do I get this to work? Thanks.
Suggestions:
You need to give the Add class a public add(...) method,
have this method accept an int parameter,
have it add a constant int to the int passed in,
and then have it return the sum.
If you want it to add two numbers, rather than a number and a constant, then give the method two int parameters, and add them together in the method.
Then create another class,
In this other class you can create an Add instance,
call the add(myInt) method,
and print the result returned.
You could try
public class Add{
public int c; // public variable
public Add() { // This is a constructor
// It will run every time you type "new Add()"
int a = 5;
int b = 5;
c = a + b;
}
}
Then, you can do this:
public class AddExtra{
public static void main(String[] args) {
Add a = new Add(); // Here, the constructor is run
int b = 5;
int c = a.c + b; // Access "a.c" because "c" is a public variable now
System.out.println(c);
}
}
Read more about constructors here.

Access object.variable in an array of objects

I need help with this piece of code.
public class ParkingLot {
static int MAX = 5;
static Car[] Slot = new Car[MAX];
public static void main(String[] args) {
Slot[0] = new Car("1234", "White");
Slot[1] = new Car("5678", "Black");
}
public static void Allot() {
for (int i = 0; i <= Slot.length; i++) {
System.out.println(Slot.getNo);
}
}
I am storing a Car Object in Slot. I wish to print/access the No and Colour of the car stored in slot. How do I go about doing that?
Well, if car has a public property, or a public getter method (this is preferable - getNumber() and getColour()), you can call them while iterating the array with the for-each loop:
for (Car car : slot) {
System.out.println(car.getColour());
}
Note that I've lowercased slot - variable names in Java should be lowercase. I'd also advise for naming the array with plural name - i.e. slots.
Note also that the way of iteration provided by others is possible, but not recommended for the basic case of iterating the whole array. Effective Java (Bloch) recommends using the foreach loop whenever possible.
Using [] notation:
public static void Allot() {
Car car;
for (int i = 0; i <= Slot.length; i++) {
// Get the car at this position in the array
car = Slot[i];
// Make sure it isn't null, since the array may not have
// a full set of cars
if (car != null) {
// Use the car reference
System.out.println(car.getNo());
}
}
}
(I assumed by the name that getNo was a method, not a property.)
E.g., Slot[0] gives you the first Car, from which you can access Car's properties and methods, so Slot[i] gives you the car at the ith position. (In the above I used a temporary variable to store the car, but you can use Slot[i].getNo() directly, it doesn't matter. I just didn't want to repeat the array lookup, even through HotSpot [the Sun JVM] will optimize it out even if I do.)
Sorry for being so late. I noticed something missing in the above answers, so here is the complete solution for the problem stated.
Here is the ParkingLot class with a call to Allot() method.
public class ParkingLot {
static int MAX = 5;
static Car[] Slot = new Car[MAX];
public static void main(String[] args) {
Slot[0] = new Car("1234", "White");
Slot[1] = new Car("5678", "Black");
Allot();
}
public static void Allot() {
for (int i = 0; i < Slot.length; i++) {
if (Slot[i] != null) {
System.out.println(Slot[i].getNo()+" , "+Slot[i].getColor());
}
}
}
}
And the Car class with the getNo() and getColor() methods.
public class Car {
private String Number;
private String Color;
Car (String Number, String Color){
this.Number = Number;
this.Color = Color;
}
public String getNo(){
return Number;
}
public String getColor(){
return Color;
}
}
class Car{
String number;
String color;
public Car(String number, String color) {
this.number = number;
this.color = color;
}
#Override
public String toString() {
return "Car{" +
"number='" + number + '\'' +
", color='" + color + '\'' +
'}';
}
}
class Test{
static int MAX = 5;
static Car[] Slot = new Car[MAX];
public static void main(String[] args) {
Slot[0] = new Car("1234", "White");
Slot[1] = new Car("5678", "Black");
for (Car car : Slot)
System.out.println(car);
}
}
you can create and access object array of objects simply like this
Object[] row={"xx","xcxcx"};
Object[] cotainer = {row,row,row};
for(int a=0;a<cotainer.length;a++){
Object[] obj = (Object[])cotainer[a];
}

Categories